Open-Source Wikis

/

Tailwind CSS

/

Packages

/

@tailwindcss/node

tailwindlabs/tailwindcss

@tailwindcss/node

Active contributors: Robin, Philipp, Jordan

Purpose

Shared Node-only helpers used by every Node-side adapter (@tailwindcss/cli, @tailwindcss/vite, @tailwindcss/postcss, @tailwindcss/webpack). The adapters need filesystem access, JS module loading, source-map post-processing, and CSS optimization through Lightning CSS — none of which the core compiler should depend on.

This package is the shim layer that keeps the compiler portable. The core tailwindcss package has zero runtime dependencies; the Node-specific surface lives here.

Directory layout

packages/@tailwindcss-node/
├── package.json
├── README.md
├── tsconfig.json
├── tsup.config.ts
└── src/
    ├── index.ts                  # Re-exports compile, optimize, source maps
    ├── index.cts                 # CommonJS variant
    ├── compile.ts                # Wraps tailwindcss.compile with Node-only loaders
    ├── env.ts                    # DEBUG flag, NODE_ENV detection
    ├── instrumentation.ts        # Timing helper used by every adapter
    ├── instrumentation.test.ts
    ├── optimize.ts               # Lightning CSS minification + vendor prefixing
    ├── source-maps.ts            # toSourceMap helper
    ├── source-maps.test.ts
    ├── urls.ts                   # Asset URL rewriting
    ├── urls.test.ts
    ├── normalize-path.ts         # Cross-platform path normalization
    ├── get-module-dependencies.ts # Resolve transitive deps for invalidation
    ├── require-cache.cts         # Sync require-cache clearer
    └── esm-cache.loader.mts      # ESM loader that mirrors require-cache.cts

Key abstractions

Symbol File Description
compile(input, opts) packages/@tailwindcss-node/src/compile.ts Wraps tailwindcss.compile with enhanced-resolve + jiti.
compileAst(ast, opts) packages/@tailwindcss-node/src/compile.ts Same, but takes an AST.
Instrumentation packages/@tailwindcss-node/src/instrumentation.ts using resource + start()/end()/hit() API.
optimize(css, opts) packages/@tailwindcss-node/src/optimize.ts Lightning CSS minify + lower modern syntax.
toSourceMap(rawMap) packages/@tailwindcss-node/src/source-maps.ts Convert decoded source map to a JSON-encoded string.
Features, Polyfills (re-exported from tailwindcss) Bit-sets the adapters use.
clearRequireCache(paths) packages/@tailwindcss-node/src/require-cache.cts Drop entries from Node's require.cache.
ESM cache loader packages/@tailwindcss-node/src/esm-cache.loader.mts Equivalent for ESM module cache.
normalizePath(p) packages/@tailwindcss-node/src/normalize-path.ts Forward-slash-only path strings.
env.DEBUG packages/@tailwindcss-node/src/env.ts Boolean derived from the DEBUG env variable.

What compile() does on top of the core

The core tailwindcss.compile accepts callback-based loaders for @import and @plugin. @tailwindcss/node's wrapper plugs in real Node loaders:

  • loadStylesheet resolves @import targets via enhanced-resolve, the same resolver Webpack uses. This means TS path aliases, package.json exports, and conditional style exports all work.
  • loadModule loads @plugin and @config files via jiti, which can run TypeScript and ESM directly without compilation.
  • onDependency(path) is invoked for every file the resolver touched, so adapters can wire those into their host's dependency graph (Vite's addWatchFile, Webpack's addDependency, PostCSS's result.messages, the CLI's watcher subscription).

compileAst is the same wrapper around tailwindcss.compileAst and is used by @tailwindcss/postcss so it can hand in an AST it already parsed.

Instrumentation

Instrumentation is a using-compatible class that batches timing data:

using I = new Instrumentation();

I.start('Compile');
// ...
I.end('Compile');

I.hit('Some thing happened', { extra: 'data' });

When the using block exits, Instrumentation flushes any open spans and (if DEBUG is on) writes a structured tree to stderr. The browser bundle uses a similar API but writes to performance.measure instead.

The class is intentionally tiny so it costs almost nothing in production builds.

optimize()

Calls Lightning CSS via bundleAsync. The function:

  • Lowers modern CSS to a target compatible with the configured browserslist (defaults baked in by Lightning CSS).
  • Optionally minifies output (minify: true).
  • Returns { code, map } where map is a decoded source map ready to be merged via @jridgewell/remapping.

Source maps are merged through magic-string and @jridgewell/remapping before being returned to adapters.

ESM/CJS dual loading

@tailwindcss/node ships both a .mjs and a .js build via tsup (tsup.config.ts), with separate type declarations. index.cts exists so legacy CJS consumers can require it. The require-cache and esm-cache.loader files are intentionally split so the two module systems can each be flushed independently when a watched dependency changes.

Integration points

  • Depends on tailwindcss (workspace).
  • Depends on enhanced-resolve (resolver), jiti (TS/ESM loader), lightningcss (optimizer), magic-string + @jridgewell/remapping + source-map-js (source map plumbing).
  • Re-exports Features, Polyfills, and Instrumentation so adapters import from one place.
  • Used by every Node-side adapter — see cli, vite, postcss, webpack.

Entry points for modification

  • Adding a new resolver condition or loader: edit compile.ts. Both loadStylesheet and loadModule are constructed there.
  • Adding a new instrumentation span type: edit instrumentation.ts. The class is small and self-contained.
  • Tweaking how source maps are merged: edit source-maps.ts. toSourceMap is the canonical conversion path.
  • Changing optimization defaults (e.g. browser targets): edit optimize.ts — Lightning CSS options are configured there.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

@tailwindcss/node – Tailwind CSS wiki | Factory