tailwindlabs/tailwindcss · error · Error

No `loadModule` function provided to `compile`

Error message

No `loadModule` function provided to `compile`

What it means

Thrown by `throwOnLoadModule()`, the default value for the `loadModule` option of `compile()`. The compile pipeline calls `loadModule` only when it encounters `@plugin` or `@config` directives in CSS that require loading a JS module from disk. If the integrator did not supply a `loadModule` callback, the default throws to signal that JS module resolution is unavailable in the current environment (e.g. a browser/WASM build, or a custom compile call without a filesystem).

Source

Thrown at packages/tailwindcss/src/index.ts:79

    base: string,
    resourceHint: 'plugin' | 'config',
  ) => Promise<{
    path: string
    base: string
    module: Plugin | Config
  }>
  loadStylesheet?: (
    id: string,
    base: string,
  ) => Promise<{
    path: string
    base: string
    content: string
  }>
}

function throwOnLoadModule(): never {
  throw new Error('No `loadModule` function provided to `compile`')
}

function throwOnLoadStylesheet(): never {
  throw new Error('No `loadStylesheet` function provided to `compile`')
}

function parseThemeOptions(params: string) {
  let options = ThemeOptions.NONE
  let prefix = null

  for (let option of segment(params, ' ')) {
    if (option === 'reference') {
      options |= ThemeOptions.REFERENCE
    } else if (option === 'inline') {
      options |= ThemeOptions.INLINE
    } else if (option === 'default') {
      options |= ThemeOptions.DEFAULT
    } else if (option === 'static') {

View on GitHub (pinned to 16e94cbf7f)

Solutions

  1. Remove the `@plugin` / `@config` directive from the CSS if you do not need JS plugins in this environment.
  2. Provide a `loadModule` callback to `compile` that resolves and imports the module (the PostCSS plugin and CLI already do this).
  3. If you are in a browser/edge runtime, port the plugin's behavior to CSS/`@theme` instead of a JS module.
  4. For v4, prefer the CSS-first config (`@theme`, `@plugin` only when you control loading) over `@config`.

Example fix

// before
import { compile } from 'tailwindcss'
// css contains: @plugin "./my-plugin.js";
let result = await compile(css)
// after
import { compile } from 'tailwindcss'
let result = await compile(css, {
  loadModule: async (id, base) => {
    let path = await resolve(id, base)
    return { path, base, module: await import(path) }
  },
})
Defensive patterns

Strategy: validation

Validate before calling

function needsLoadModule(css: string): boolean {
  return /@plugin\s+|@config\s+/.test(css);
}
// Before calling compile:
if (needsLoadModule(css) && typeof options.loadModule !== 'function') {
  throw new Error('CSS uses @plugin/@config but no loadModule was provided');
}

Type guard

function hasLoadModule(opts: CompileOptions): opts is CompileOptions & { loadModule: NonNullable<CompileOptions['loadModule']> } {
  return typeof opts.loadModule === 'function';
}

Try / catch

try {
  await compile(css, opts);
} catch (e) {
  if (e instanceof Error && e.message === 'No `loadModule` function provided to `compile`') {
    // either remove @plugin/@config or supply a loadModule
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `compile(css, { ... })` without a `loadModule` option while the CSS contains `@plugin "./my-plugin.js"` or `@config "./tailwind.config.js"`. The standalone `compile` export defaults `loadModule` to `throwOnLoadModule`, so any `@plugin`/`@config` triggers it. Browsers and constrained runtimes cannot load filesystem modules, hence the guard.

Common situations: Using the Tailwind v4 compiler in a browser/WASM/edge environment where `@plugin` or `@config` is present but no FS loader exists; calling the low-level `compile` API directly (instead of the PostCSS plugin or CLI which wire up `loadModule`); keeping a `@config` directive after migrating to v4.

Related errors


AI-assisted analysis of tailwindlabs/tailwindcss@16e94cbf7f (2026-08-12). Data as JSON: /api/errors/13510cf82993d173. Report an issue: GitHub.