# Tailwind CSS Administrator & Developer Guide

**Tailwind CSS v4.2.2** — utility-first CSS framework reimagined as a full compiler  
**License:** MIT | **Source:** `tailwindlabs/tailwindcss` @ `5a835e1`

Tailwind CSS v4 is a ground-up rewrite that replaces the JavaScript-driven PostCSS plugin architecture of v3 with a standalone CSS compiler built on a Rust extraction engine, a TypeScript AST pipeline, and first-party integrations for every major build tool. This guide covers the internal architecture, build system, configuration surface, deployment patterns, security posture, and developer workflows necessary to operate, extend, and troubleshoot Tailwind CSS at scale.

---

## 1. Architecture Overview

### 1.1 High-Level Data Flow

```
Source Files (.html, .jsx, .vue, ...)
        │
        ▼
┌─────────────────────┐
│   Oxide Scanner     │  Rust (napi-rs)
│   (crates/oxide)    │  State-machine candidate extraction
└────────┬────────────┘
         │ candidate strings
         ▼
┌─────────────────────┐
│   CSS Compiler      │  TypeScript
│   (packages/        │  Parse → Resolve → Compile → Optimize
│    tailwindcss)     │
└────────┬────────────┘
         │ CSS AST
         ▼
┌─────────────────────┐
│   Optimization      │  lightningcss
│   Minification      │  (via @tailwindcss-node)
│   Source Maps        │
└────────┬────────────┘
         │
         ▼
    Output CSS file
```

The compiler operates in two distinct phases:

1. **Scan phase** — The Rust-based oxide engine traverses source files, applies language-specific pre-processors, and runs a battery of state machines to extract candidate class strings. This is CPU-bound, parallelized via `rayon`, and SIMD-optimized for whitespace skipping.

2. **Generate phase** — The TypeScript compiler receives candidate strings, resolves them against the design system (theme values, registered utilities, registered variants), applies `@apply` directives, resolves `@import` chains, and emits a CSS AST that gets serialized and optionally optimized through `lightningcss`.

### 1.2 Monorepo Layout

The repository is a **dual workspace**: pnpm manages TypeScript/JavaScript packages; Cargo manages Rust crates. Turborepo (`turbo`) orchestrates cross-language builds.

```
tailwindcss/
├── packages/
│   ├── tailwindcss/              Core CSS compiler (TS)
│   ├── @tailwindcss-cli/         CLI binary
│   ├── @tailwindcss-postcss/     PostCSS plugin
│   ├── @tailwindcss-vite/        Vite plugin
│   ├── @tailwindcss-webpack/     Webpack loader
│   ├── @tailwindcss-node/        Node.js integration layer
│   ├── @tailwindcss-browser/     In-browser compiler
│   ├── @tailwindcss-standalone/  Standalone Bun-built binary
│   ├── @tailwindcss-upgrade/     v3→v4 migration tool
│   └── @tailwindcss-oxide/       N-API bindings for Rust
├── crates/
│   ├── oxide/                    Core extraction engine (Rust)
│   ├── node/                     N-API bridge (Rust)
│   ├── ignore/                   .gitignore matcher (forked from ripgrep)
│   └── classification-macros/    Proc macros for byte classification
├── integrations/                 Integration test suites
├── playgrounds/                  Dev playgrounds
└── oxide/                        Rust workspace root
```

### 1.3 Package Dependency Graph

```
@tailwindcss-cli ──────────┐
@tailwindcss-postcss ──────┤
@tailwindcss-vite ─────────┤
@tailwindcss-webpack ──────┤
                           ▼
                   @tailwindcss-node
                           │
                     ┌─────┴─────┐
                     ▼           ▼
              tailwindcss   @tailwindcss-oxide
                     │           │
                     │     ┌─────┘
                     ▼     ▼
              (lightningcss, enhanced-resolve,
               jiti, source-map-js)
```

Every build tool integration depends on `@tailwindcss-node`, which provides module resolution, optimization, and the bridge to the core compiler. The core `tailwindcss` package has zero Node.js dependencies — it is pure TypeScript operating on CSS ASTs.

### 1.4 Technology Stack

| Layer | Technology | Purpose |
|---|---|---|
| Class extraction | Rust + napi-rs | Performance-critical candidate parsing |
| CSS compiler | TypeScript | AST manipulation, utility generation, variant application |
| CSS optimization | lightningcss | Minification, vendor prefixing, modern CSS transforms |
| Module resolution | enhanced-resolve | CSS `@import`, plugin/config resolution |
| TS config loading | jiti | Load `.ts` config files without pre-compilation |
| Source manipulation | magic-string | Efficient string mutations with source map support |
| File watching | @parcel/watcher | Native filesystem events for `--watch` mode |
| Parallel scanning | rayon | Thread-pool parallelism in Rust oxide |
| Test framework | vitest + Playwright | Unit/integration tests + browser E2E |
| Build orchestration | turbo + tsup + Cargo | Monorepo task graph with caching |
| Package management | pnpm 9.6.0 | Workspace linking with strict dependency hoisting |

---

## 2. System Requirements

### 2.1 Build-Time Requirements

| Requirement | Minimum | Recommended |
|---|---|---|
| Node.js | 18.x | 20.x or 22.x (LTS) |
| pnpm | 9.6.0 | 9.6.0+ (version pinned in `packageManager`) |
| Rust | stable (edition 2021) | Latest stable via rustup |
| Cargo | Included with Rust | — |
| Python | 3.x (for node-gyp) | Only needed for native module compilation |
| OS | Linux x64/arm64, macOS x64/arm64, Windows x64 | Linux x64 for CI |

> [!IMPORTANT]
> The Rust toolchain is only required when building oxide from source. Published npm packages include pre-built platform binaries for 12 targets: linux-x64-gnu, linux-x64-musl, linux-arm64-gnu, linux-arm64-musl, darwin-x64, darwin-arm64, win32-x64-msvc, win32-arm64-msvc, freebsd-x64, android-arm64, android-arm-eabi, and wasm32-wasi-preview1-threads.

### 2.2 Runtime Requirements

For end users consuming published packages:

| Integration | Node.js | Additional |
|---|---|---|
| CLI (`@tailwindcss/cli`) | 18+ | None |
| PostCSS plugin | 18+ | PostCSS 8.x |
| Vite plugin | 18+ | Vite 5.x or 6.x (7.x supported via Environment API) |
| Webpack loader | 18+ | Webpack 5.x |
| Standalone binary | None | Self-contained Bun executable |
| Browser build | None | Modern browser with MutationObserver |

### 2.3 Platform Binary Matrix

The `@tailwindcss-oxide` package publishes platform-specific npm packages using the napi-rs convention:

| Platform | Architecture | Package |
|---|---|---|
| Linux (glibc) | x64 | `@tailwindcss/oxide-linux-x64-gnu` |
| Linux (glibc) | arm64 | `@tailwindcss/oxide-linux-arm64-gnu` |
| Linux (musl) | x64 | `@tailwindcss/oxide-linux-x64-musl` |
| Linux (musl) | arm64 | `@tailwindcss/oxide-linux-arm64-musl` |
| macOS | x64 | `@tailwindcss/oxide-darwin-x64` |
| macOS | arm64 | `@tailwindcss/oxide-darwin-arm64` |
| Windows | x64 | `@tailwindcss/oxide-win32-x64-msvc` |
| Windows | arm64 | `@tailwindcss/oxide-win32-arm64-msvc` |
| FreeBSD | x64 | `@tailwindcss/oxide-freebsd-x64` |
| Android | arm64 | `@tailwindcss/oxide-android-arm64` |
| Android | arm (eabi) | `@tailwindcss/oxide-android-arm-eabi` |
| WASM | wasi | `@tailwindcss/oxide-wasm32-wasi-preview1-threads` |

> [!WARNING]
> Linux ARM64 users have reported missing native module errors when the correct platform package is not installed. This commonly occurs in Docker multi-arch builds or when using npm instead of pnpm (which handles optional dependencies differently). See GitHub issue #15806. Ensure your package manager installs optional dependencies, or use the standalone binary as a workaround.

### 2.4 Standalone Binary

The standalone binary (`@tailwindcss/standalone`) bundles the full compiler into a single executable built with Bun. It includes the official plugins (`@tailwindcss/forms`, `@tailwindcss/typography`, `@tailwindcss/aspect-ratio`) and requires no Node.js runtime.

Platform binaries:
- `tailwindcss-linux-x64`
- `tailwindcss-linux-arm64`
- `tailwindcss-macos-x64`
- `tailwindcss-macos-arm64`
- `tailwindcss-windows-x64.exe`

Module resolution in standalone mode uses `globalThis.__tw_resolve` and `globalThis.__tw_load` — custom shims that resolve against the bundled module graph rather than the filesystem.

---

## 3. Configuration Reference

### 3.1 CSS-First Configuration (v4 Model)

Tailwind CSS v4 replaces `tailwind.config.js` with CSS-native configuration. All customization happens inside your CSS file using at-rules:

```css
@import "tailwindcss";

/* Theme customization */
@theme {
  --color-primary: #3b82f6;
  --font-sans: "Inter", sans-serif;
  --breakpoint-3xl: 1920px;
}

/* Source detection */
@source "../components/**/*.tsx";

/* Plugin loading */
@plugin "@tailwindcss/forms";

/* Custom variant */
@variant dark (&:where(.dark, .dark *));
```

### 3.2 CSS At-Rules Reference

| At-Rule | Purpose | Example |
|---|---|---|
| `@import "tailwindcss"` | Load the full framework (preflight + theme + utilities) | `@import "tailwindcss"` |
| `@theme` | Define or override design tokens | `@theme { --color-brand: #f00; }` |
| `@theme inline` | Define theme values that inline rather than emit CSS variables | `@theme inline { --color-*: initial; }` |
| `@theme reference` | Import theme for tooling without emitting CSS | `@theme reference { ... }` |
| `@source` | Add glob patterns for candidate scanning | `@source "../app/**/*.html"` |
| `@source not` | Exclude paths from scanning | `@source not "./legacy/**"` |
| `@plugin` | Load a JS/TS plugin | `@plugin "./my-plugin.ts"` |
| `@config` | Load a JS/TS config file (v3 compat) | `@config "./tailwind.config.ts"` |
| `@variant` | Register a custom variant | `@variant hocus (&:hover, &:focus)` |
| `@custom-variant` | Alias for `@variant` | Same syntax |
| `@utility` | Define a custom utility | `@utility tab-* { tab-size: --value(--tab-*); }` |
| `@apply` | Inline utility classes | `.btn { @apply px-4 py-2 rounded; }` |
| `@reference` | Import for reference only (no output) | `@reference "tailwindcss"` |
| `@tailwind` | Legacy directive (v3 compat, mapped internally) | `@tailwind utilities` |

> [!NOTE]
> The `@import "tailwindcss"` directive is the canonical entry point. It expands to `@import "tailwindcss/preflight.css"`, `@import "tailwindcss/theme.css"`, and `@import "tailwindcss/utilities.css"`. You can import these individually for granular control.

### 3.3 Theme Namespace Reference

Theme values are CSS custom properties organized by namespace. Each namespace maps to a set of utilities:

| Namespace | Utilities | Example Token |
|---|---|---|
| `--color-*` | `text-*`, `bg-*`, `border-*`, `ring-*`, etc. | `--color-blue-500: #3b82f6` |
| `--font-*` | `font-*` | `--font-sans: "Inter", sans-serif` |
| `--font-size-*` | `text-*` | `--font-size-lg: 1.125rem` |
| `--font-weight-*` | `font-*` | `--font-weight-bold: 700` |
| `--tracking-*` | `tracking-*` | `--tracking-tight: -0.025em` |
| `--leading-*` | `leading-*` | `--leading-relaxed: 1.625` |
| `--breakpoint-*` | Responsive variants (`sm:`, `md:`, etc.) | `--breakpoint-md: 768px` |
| `--spacing-*` | `p-*`, `m-*`, `gap-*`, `w-*`, `h-*`, etc. | `--spacing-4: 1rem` |
| `--radius-*` | `rounded-*` | `--radius-lg: 0.5rem` |
| `--shadow-*` | `shadow-*` | `--shadow-md: 0 4px 6px ...` |
| `--inset-shadow-*` | `inset-shadow-*` | `--inset-shadow-sm: inset 0 1px ...` |
| `--drop-shadow-*` | `drop-shadow-*` | `--drop-shadow-lg: 0 10px 8px ...` |
| `--blur-*` | `blur-*` | `--blur-md: 12px` |
| `--width-*` | `w-*` | `--width-prose: 65ch` |
| `--z-*` | `z-*` | `--z-50: 50` |
| `--opacity-*` | `opacity-*` | `--opacity-50: 0.5` |
| `--ease-*` | `ease-*` (transition-timing-function) | `--ease-in-out: cubic-bezier(...)` |
| `--animate-*` | `animate-*` | `--animate-spin: spin 1s linear infinite` |
| `--container-*` | `@container` queries | `--container-3xl: 1536px` |

### 3.4 CSS Functions

Tailwind v4 provides CSS functions that resolve against the design system:

| Function | Purpose | Example |
|---|---|---|
| `--theme(...)` | Reference a theme value by its token path | `color: --theme(--color-blue-500)` |
| `--spacing(...)` | Reference the spacing scale | `margin: --spacing(4)` |
| `--alpha(color, opacity)` | Apply alpha to a theme color | `color: --alpha(--color-blue-500, 50%)` |

> [!CAUTION]
> `--spacing()` requires an argument. Calling it without one produces the error: *"The --spacing(...) function requires an argument"* (`css-functions.ts:49`). Similarly, `--theme()` only works with CSS variables from your theme — using it with arbitrary values produces: *"The --theme(...) function can only be used with CSS variables from your theme"* (`css-functions.ts:75`).

### 3.5 Environment Variables

| Variable | Package | Purpose |
|---|---|---|
| `DEBUG` | `@tailwindcss-node` | Enable debug logging when set (checked in `env.ts`) |
| `NODE_ENV` | `@tailwindcss-postcss` | When `production`, enables optimization passes |
| `NODE_PATH` | `@tailwindcss-node` | Additional module resolution paths (passed to enhanced-resolve) |

### 3.6 Build Tool Configuration

#### CLI Options

```
tailwindcss build [options]

Options:
  -i, --input <path>    Input CSS file (use "-" for stdin)
  -o, --output <path>   Output CSS file (use "-" for stdout)
  -w, --watch           Watch for changes and rebuild
  --minify              Minify the output CSS
  -h, --help            Show help

Commands:
  build                 Build CSS (default)
  canonicalize          Output sorted/canonical CSS
```

> [!TIP]
> The CLI supports stdin/stdout piping for CI integration: `cat input.css | tailwindcss build -i - -o -`. The `canonicalize` command is useful for diffing CSS output across versions — it produces a deterministic sort order.

#### PostCSS Plugin

```js
// postcss.config.js
module.exports = {
  plugins: {
    "@tailwindcss/postcss": {
      // Options (all optional):
      base: "./src",        // Base directory for file resolution
      optimize: {
        minify: true        // Enable CSS minification
      }
    }
  }
};
```

The PostCSS plugin maintains an LRU cache of compiled CSS roots. It performs incremental rebuilds when source files change and full rebuilds when the CSS input itself changes. AST conversion between PostCSS nodes and Tailwind's internal AST happens bidirectionally.

#### Vite Plugin

```js
// vite.config.ts
import tailwindcss from "@tailwindcss/vite";

export default {
  plugins: [
    tailwindcss({
      // Options (all optional):
      optimize: {
        minify: true        // Enable CSS minification (defaults to mode-based)
      }
    })
  ]
};
```

**Two-step architecture:**
1. **Scan step** (`enforce: "pre"`) — intercepts CSS imports, registers them for processing, injects module graph tracking.
2. **Generate step** (no enforce) — compiles CSS with extracted candidates, handles HMR updates.

The plugin supports the Vite Environment API (Vite 7+) for SSR-aware builds. CSS changes trigger HMR updates; template changes that introduce new candidates trigger a full page reload.

#### Webpack Loader

```js
// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "@tailwindcss/webpack",
            options: {
              base: "./src",       // Base directory
              optimize: {
                minify: true       // Enable minification
              }
            }
          }
        ]
      }
    ]
  }
};
```

The Webpack loader uses an LRU cache (max 50 entries) with mtime-based invalidation. It performs a quick bail check on CSS files — if the content contains none of `@import`, `@reference`, `@theme`, `@variant`, `@config`, `@plugin`, `@apply`, or `@tailwind`, it skips processing entirely. CSS Modules are supported; when detected, the `@property` polyfill is disabled to avoid conflicts.

---

## 4. Deployment & Scaling

### 4.1 Integration Patterns

| Pattern | Tool | When to Use |
|---|---|---|
| **Vite plugin** | `@tailwindcss/vite` | Vite-based projects (recommended for new projects) |
| **PostCSS plugin** | `@tailwindcss/postcss` | Existing PostCSS pipelines, Next.js, Nuxt |
| **Webpack loader** | `@tailwindcss/webpack` | Webpack 5 projects |
| **CLI** | `@tailwindcss/cli` | Framework-agnostic, CI/CD pipelines |
| **Standalone** | `@tailwindcss/standalone` | No Node.js runtime available, Docker scratch images |
| **Browser** | `@tailwindcss/browser` | Playgrounds, CodePen, prototyping |

### 4.2 CI/CD Build Optimization

**Caching strategy:**

The oxide scanner and CSS compiler are deterministic — same inputs always produce the same outputs. Cache the following:

1. **Node modules** — `node_modules/.pnpm/` (or equivalent for your package manager)
2. **Turbo cache** — `.turbo/` if building from source
3. **Standalone binary** — download once per version, cache across builds

**Build performance tips:**

- The Rust oxide scanner is the fastest path. Avoid falling back to JS-based scanning.
- Use `@source` directives to limit the scanning scope. The auto-detection scans everything not in `.gitignore`, which can be expensive in large monorepos.
- The `@source not` directive prunes entire directory trees from scanning.
- For Docker builds, use multi-stage builds and copy only source files needed for CSS compilation.

### 4.3 Docker Considerations

```dockerfile
# Multi-stage build example
FROM node:20-slim AS build
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile
COPY . .
RUN pnpm tailwindcss build -i src/input.css -o dist/output.css --minify

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
```

> [!WARNING]
> Docker bind mounts can cause issues with the CLI's file watcher (`@parcel/watcher`). The native filesystem events may not propagate correctly through bind mounts on some host OS/Docker runtime combinations. See GitHub issue #18540. Use polling mode or volume mounts as a workaround.

### 4.4 Source Detection and Auto-Content

The oxide scanner performs automatic source detection:

1. Starts from the CSS file's directory (or project root).
2. Walks the directory tree, respecting `.gitignore` patterns.
3. Skips binary file extensions, `node_modules`, `.git`, and other known non-source directories.
4. Applies language-specific pre-processors to extract class candidates from templates.

**Pre-processors by file type:**

| Language/Format | Pre-processing |
|---|---|
| Clojure | Keyword extraction from hiccup syntax |
| Elixir | HEEx template handling |
| Haml | Attribute extraction |
| JSON | String value extraction |
| Markdown | Fenced code block handling |
| Pug | Class attribute extraction |
| Razor | `.cshtml` attribute handling |
| Ruby | ERB template handling |
| Rust | Macro string extraction |
| Slim | Attribute extraction |
| Svelte | Template + script handling |
| Vue | SFC `<template>` + `<script>` handling |

**Ignore patterns (built-in):**

The scanner automatically ignores files with these extensions: `.avif`, `.bmp`, `.csv`, `.gif`, `.ico`, `.jar`, `.jpeg`, `.jpg`, `.lock`, `.map`, `.mp3`, `.mp4`, `.ogg`, `.otf`, `.pdf`, `.png`, `.svg`, `.ttf`, `.wav`, `.webm`, `.webp`, `.woff`, `.woff2`, `.zip` (and others). Directories like `node_modules`, `.git`, `.svn`, `.hg` are also skipped.

---

## 5. Operations

### 5.1 Build Modes

**Full build** — Processes all CSS from scratch. Occurs on first build or when the CSS input file changes structurally (new `@theme`, `@plugin`, `@import` directives).

**Incremental build** — Only reprocesses changed candidates. Occurs when source files (templates, components) change but the CSS configuration remains the same. The PostCSS plugin, Vite plugin, and Webpack loader all support incremental builds.

**Watch mode** — Available via CLI (`--watch`) and implicitly in Vite/Webpack dev servers. Uses `@parcel/watcher` for native filesystem events. Triggers incremental or full rebuilds as appropriate.

### 5.2 Diagnostic Output and Debugging

Set the `DEBUG` environment variable to enable verbose logging from `@tailwindcss-node`:

```bash
DEBUG=1 tailwindcss build -i input.css -o output.css
```

**Common error messages and their causes:**

| Error | Source | Cause |
|---|---|---|
| `Cannot apply unknown utility class` | `apply.ts:242` | `@apply` references a class that doesn't exist in the design system |
| `You cannot use @apply inside @keyframes` | `apply.ts:36` | `@apply` used inside a `@keyframes` block (not supported) |
| `Circular dependency detected in custom variants` | `index.ts:639` | Variant A references variant B which references variant A |
| `Missing opening {` | `css-parser.ts:427` | Malformed CSS — unbalanced braces |
| `Invalid theme value` | `theme.ts:63` | Theme token references a value that doesn't exist |
| `Could not resolve '{id}' from '{base}'` | `compile.ts:127,140,165` | Module resolution failed for `@import`, `@plugin`, or `@config` |
| `The browser build does not support @import` | `browser/index.ts:149` | External `@import` used in browser build |
| `The browser build does not support plugins or config files` | `browser/index.ts:174` | `@plugin` or `@config` used in browser build |

### 5.3 Migration from v3 to v4

The `@tailwindcss/upgrade` package provides an automated migration tool:

```bash
npx @tailwindcss/upgrade
```

**What it migrates:**

| Area | Transformations |
|---|---|
| CSS directives | `@tailwind base/components/utilities` → `@import "tailwindcss"` |
| CSS imports | Layer-based imports → standard imports |
| `@apply` | Updates class names to v4 equivalents |
| Theme references | `theme('colors.blue.500')` → `var(--color-blue-500)` or `--theme(--color-blue-500)` |
| Preflight | Updates preflight references |
| Variants | Migrates deprecated variant syntax |
| Template classes | Updates renamed/removed utility classes |
| Arbitrary values | Updates deprecated arbitrary value syntax |
| Legacy classes | Maps v3 classes to v4 equivalents |
| JS config | Migrates `tailwind.config.js` values into CSS `@theme` blocks |
| PostCSS config | Updates PostCSS configuration for v4 plugin |
| Prefix migration | Translates `tw-` prefix patterns to v4 approach |

The upgrade tool uses `tree-sitter` and `tree-sitter-typescript` for robust template parsing — it does not rely on regex for JavaScript/TypeScript source transformations.

### 5.4 Monitoring Build Health

Key metrics to track in production build pipelines:

- **Build time** — Full builds should take <2s for typical projects. >5s indicates excessive source scanning scope.
- **Output size** — Minified CSS should be proportional to utility usage. Sudden size jumps indicate possible `@apply` proliferation or theme bloat.
- **Candidate count** — Monitor how many unique candidates the scanner extracts. False positives (strings that look like classes but aren't) increase compile time without affecting output.
- **Source map validity** — SOURCEMAP_BROKEN warnings (see issue #19930) can appear in Nuxt/Vite setups due to source map chain breaks.

---

## 6. Performance

### 6.1 Oxide Scanner Architecture

The Rust oxide engine is the performance-critical path. It uses a hierarchy of state machines to extract candidate class strings from arbitrary source files:

```
Input bytes
    │
    ├─► Language pre-processor (optional)
    │
    ├─► Fast skip (SIMD whitespace detection)
    │
    └─► State machine cascade:
        ├── CandidateMachine (top-level dispatcher)
        │   ├── UtilityMachine (e.g., "bg-blue-500")
        │   ├── VariantMachine (e.g., "hover:")
        │   ├── NamedUtilityMachine (e.g., "text-lg")
        │   ├── NamedVariantMachine (e.g., "group-hover:")
        │   ├── ArbitraryPropertyMachine (e.g., "[color:red]")
        │   ├── ArbitraryValueMachine (e.g., "bg-[#f00]")
        │   ├── ArbitraryVariableMachine (e.g., "bg-(--my-var)")
        │   ├── CssVariableMachine (e.g., "--tw-bg-opacity")
        │   ├── ModifierMachine (e.g., "/50")
        │   └── StringMachine (quoted strings)
        │
        └─► Extracted candidates (deduplicated)
```

**Key optimizations:**

1. **SIMD fast-skip** — Uses SIMD instructions to skip over large whitespace regions without entering state machines.
2. **Byte classification macros** — The `classification-macros` crate provides `#[bytes(...)]` and `#[bytes_range(...)]` proc macros that generate lookup tables for O(1) byte classification.
3. **Rayon parallelism** — File scanning is parallelized across CPU cores via `rayon`'s work-stealing thread pool.
4. **Glob hoisting** — The scanner optimizes glob patterns by hoisting common prefixes, reducing directory traversal.
5. **Language pre-processors** — Strip non-relevant syntax before candidate extraction, reducing false positives and improving throughput.

### 6.2 N-API Bridge

The `@tailwindcss-oxide` package exposes the Rust scanner to Node.js via napi-rs:

```typescript
class Scanner {
  constructor(options: {
    sources: Array<{ base: string; pattern?: string }>;
    globs?: Array<{ origin?: string; base: string; pattern: string }>;
  })

  scan(): string[]                    // Scan all sources, return candidates
  scan_files(files: string[]): string[] // Scan specific files
  files(): string[]                    // List discovered source files
  globs(): Array<{ base: string; pattern: string }>  // Active glob patterns
  normalized_sources(): Array<{ base: string; pattern: string }>
}
```

The N-API bridge in `crates/node` handles type conversion between Rust and JavaScript. Scanned results are deduplicated in Rust before crossing the N-API boundary to minimize serialization overhead.

### 6.3 CSS Compiler Performance

The TypeScript compiler processes candidates through several stages:

1. **Candidate parsing** — Each candidate string is parsed into a structured `Candidate` type (static, functional, or arbitrary).
2. **Utility resolution** — Candidates are matched against registered utilities. Theme values are resolved lazily.
3. **Variant application** — Variants are applied as wrappers around the resolved utility CSS.
4. **AST construction** — CSS AST nodes are created and deduplicated.
5. **@apply expansion** — Inline utility references are expanded recursively.
6. **Serialization** — The AST is serialized to a CSS string.

**Incremental compilation** reuses the design system state and only processes new candidates. The LRU caches in PostCSS (unbounded) and Webpack (max 50) store compiled results keyed by input CSS content hash.

### 6.4 lightningcss Optimization

The `@tailwindcss-node` package applies lightningcss for:

- **Minification** — Whitespace removal, shorthand collapsing, value optimization.
- **Vendor prefixing** — Based on browserslist targets.
- **Modern CSS transforms** — Lowers newer CSS features for older browsers.
- **Nesting flattening** — Resolves CSS nesting for browsers that don't support it.
- **`@property` polyfill** — Generates `@property` rules for registered custom properties (disabled in CSS Modules mode).

### 6.5 Performance Bottlenecks

Common bottlenecks in order of impact:

1. **Source scanning scope** — Scanning too many files is the #1 performance issue. Use `@source` to limit scope.
2. **`@apply` chains** — Each `@apply` triggers a mini-compilation. Deep chains compound.
3. **Plugin count** — Each plugin runs synchronously during compilation.
4. **Import resolution** — Deep `@import` chains require filesystem I/O for each resolution.
5. **Source map generation** — Adds ~10-20% overhead. Disable in production if not needed.

---

## 7. Security

### 7.1 Supply Chain Security

**Published packages:**

- All packages are published to npm under the `@tailwindcss` scope (owned by Tailwind Labs).
- Platform-specific oxide binaries are published as separate packages with `optionalDependencies` — npm/pnpm downloads only the binary for the current platform.
- The standalone binary is self-contained; no runtime dependency resolution occurs.

**Native binary provenance:**

The oxide binaries are compiled in CI from the `crates/` source. The napi-rs build system cross-compiles for all 12 targets. The binary integrity is verified by npm's content-addressable storage (integrity hashes in lockfiles).

> [!CAUTION]
> When using the standalone binary outside of npm (e.g., downloaded directly from GitHub releases), verify the binary hash against the published checksums. The standalone binary bundles `@tailwindcss/forms`, `@tailwindcss/typography`, and `@tailwindcss/aspect-ratio` — ensure these are versions you trust.

### 7.2 Configuration Injection Vectors

| Vector | Risk | Mitigation |
|---|---|---|
| `@plugin` directive | Executes arbitrary JS/TS | Only use trusted plugins. Plugin code runs with full Node.js permissions. |
| `@config` directive | Loads arbitrary JS/TS config | Same as plugin — runs with full process permissions. |
| Arbitrary values in classes | CSS injection via `[content:'...']` | Tailwind sanitizes values, but complex expressions should be audited. |
| `@import` resolution | Path traversal | `enhanced-resolve` follows symlinks and can resolve outside project root. |
| Template scanning | Information disclosure | Scanner reads file contents. In CI, limit source paths to prevent scanning secrets. |

> [!WARNING]
> The `@plugin` and `@config` directives execute arbitrary JavaScript with the same permissions as the Node.js process. In CI environments, treat CSS files as code — a malicious `@plugin "./exfil.js"` directive in a CSS file could exfiltrate secrets. Apply the same review rigor to CSS files as you would to `package.json` scripts.

### 7.3 CSS Injection Considerations

Tailwind's utility-class approach reduces traditional CSS injection risks because:

1. **No runtime CSS generation** — CSS is compiled at build time, not at request time.
2. **Deterministic output** — Same input always produces same output; no user input influences CSS at runtime.
3. **Arbitrary value sanitization** — The compiler validates arbitrary values (e.g., `bg-[url('...')]`) during parsing.

However, the **browser build** (`@tailwindcss/browser`) compiles CSS at runtime in the client. In this mode:

- Class attributes from the DOM are used as compiler input.
- A malicious DOM mutation could inject unexpected CSS.
- The browser build should only be used for trusted content (prototyping, documentation, playgrounds).

> [!IMPORTANT]
> Never use `@tailwindcss/browser` in production applications where untrusted content can modify DOM class attributes. The MutationObserver-based scanning means any DOM change triggers recompilation with the new class values.

### 7.4 Content Security Policy (CSP)

The browser build injects `<style>` elements dynamically, requiring `style-src 'unsafe-inline'` or a nonce-based CSP. For build-time compilation (CLI, Vite, PostCSS, Webpack), no special CSP headers are needed — the output is a static CSS file.

### 7.5 Dependency Audit Surface

Core runtime dependencies (minimal attack surface):

| Package | Purpose | Risk Profile |
|---|---|---|
| `lightningcss` | CSS optimization | Rust binary, Mozilla-maintained |
| `enhanced-resolve` | Module resolution | Webpack team, filesystem access |
| `jiti` | TS config loading | Executes code, `import()` with fallback |
| `@parcel/watcher` | File watching (CLI only) | Native binary, Parcel team |
| `magic-string` | Source manipulation | Pure JS, well-audited |
| `source-map-js` | Source map support | Pure JS, Mozilla fork |

The core `tailwindcss` package has **zero runtime npm dependencies**. All dependencies come from the integration packages (`@tailwindcss-node`, `@tailwindcss-cli`, etc.).

---

## 8. Developer Internals

### 8.1 Core Compiler (`packages/tailwindcss`)

The core package (55 files, ~1.1M characters) is the heart of the framework. It exports three primary entry points:

```typescript
// Main compilation entry
function compile(
  css: string,
  options?: { base?: string; from?: string }
): Promise<{
  globs: Glob[];
  build(candidates: string[]): string;
  buildWithMaps(candidates: string[]): { css: string; map: SourceMap };
}>

// AST-level compilation
function compileAst(
  ast: AstNode[],
  options?: { base?: string; from?: string }
): Promise<{
  globs: Glob[];
  build(candidates: string[]): string;
}>

// Design system introspection (IntelliSense, tooling)
function __unstable__loadDesignSystem(
  css: string,
  options?: { base?: string }
): Promise<DesignSystem>
```

> [!NOTE]
> The `__unstable__loadDesignSystem` export is used by the Tailwind CSS IntelliSense VS Code extension and other tooling. Despite the `__unstable__` prefix, it is actively maintained and versioned alongside the compiler. It provides the full design system state including all registered utilities, variants, and theme values.

### 8.2 Key Internal Types

#### DesignSystem

The central object that holds all compiler state:

```typescript
interface DesignSystem {
  theme: Theme
  utilities: Map<string, UtilityDefinition>
  variants: Map<string, VariantDefinition>
  // Internal compiler state
  features: Features
  polyfills: Polyfills
}
```

#### Theme

The theme is a CSS custom property store with namespace awareness:

```typescript
class Theme {
  // Resolve a theme value by its full path
  resolve(path: string): string | undefined

  // Resolve with namespace awareness (e.g., "--color-" namespace)
  resolveNamespaced(namespace: string, key: string): string | undefined

  // Check if a namespace has any values
  hasNamespace(namespace: string): boolean
}
```

#### AstNode

The CSS AST is a union type:

```typescript
type AstNode =
  | { kind: "rule"; selector: string; nodes: AstNode[] }
  | { kind: "at-rule"; name: string; params: string; nodes: AstNode[] }
  | { kind: "declaration"; property: string; value: string; important: boolean }
  | { kind: "comment"; value: string }
  | { kind: "context"; context: Record<string, string>; nodes: AstNode[] }
  | { kind: "at-root"; nodes: AstNode[] }
```

#### Features (Bitflags)

```typescript
enum Features {
  None = 0,
  AtApply = 1 << 0,        // @apply directives present
  JsPluginCompat = 1 << 1, // JS plugin compatibility mode
  ThemeFunction = 1 << 2,  // --theme() function used
  Utilities = 1 << 3       // Utility generation needed
}
```

#### Polyfills (Bitflags)

```typescript
enum Polyfills {
  All = ~0,
  AtProperty = 1 << 0  // @property rule generation
}
```

#### Candidate

Parsed utility class representation:

```typescript
type Candidate =
  | { kind: "static"; value: string; variants: Variant[]; important: boolean }
  | { kind: "functional"; value: string; modifier?: string; variants: Variant[]; important: boolean }
  | { kind: "arbitrary"; property: string; value: string; variants: Variant[]; important: boolean }
```

#### Variant

```typescript
type Variant =
  | { kind: "static"; value: string }
  | { kind: "functional"; value: string; modifier?: string }
  | { kind: "compound"; value: string; inner: Variant }
  | { kind: "arbitrary"; selector: string }
```

### 8.3 CSS Parser (`css-parser.ts`)

The custom CSS parser handles Tailwind-specific extensions while maintaining CSS spec compliance. It produces `AstNode[]` from raw CSS strings.

Key behaviors:
- Handles `@theme`, `@plugin`, `@config`, `@source`, `@variant`, `@utility`, `@apply`, `@reference` as first-class at-rules.
- Preserves comments in the AST for source map fidelity.
- Reports structured errors with line/column information (e.g., `Missing opening {` at `css-parser.ts:427`).
- Supports CSS nesting syntax natively.

### 8.4 Utility Registration and Resolution

Utilities are registered via the design system, either from the built-in set or via plugins:

```typescript
// Static utility (fixed CSS output)
designSystem.utilities.set("sr-only", {
  // CSS declarations
});

// Functional utility (value-parameterized)
designSystem.utilities.set("bg-*", {
  // Resolve value from theme or arbitrary, generate CSS
});
```

The resolution process:
1. Parse candidate string into `Candidate` structure.
2. Look up utility by name in the registry.
3. For functional utilities, resolve the value against the theme namespace.
4. Apply any modifier (e.g., `/50` for opacity).
5. Wrap in variant selectors (applied outside-in).
6. Return CSS AST nodes.

### 8.5 Variant System

Variants transform utility selectors. They are composable (stackable) and ordered by specificity:

**Built-in variant categories:**
- **Pseudo-class:** `hover`, `focus`, `active`, `visited`, `first-child`, `last-child`, etc.
- **Pseudo-element:** `before`, `after`, `placeholder`, `file`, `marker`, `selection`, etc.
- **Responsive:** `sm`, `md`, `lg`, `xl`, `2xl` (from `--breakpoint-*` theme)
- **Dark mode:** `dark` (configurable: media query or class-based)
- **Container queries:** `@sm`, `@md`, `@lg`, etc.
- **State:** `open`, `closed`, `disabled`, `enabled`, `checked`, `indeterminate`, etc.
- **Group/peer:** `group-hover`, `peer-focus`, etc.
- **Arbitrary:** `[&:nth-child(3)]`, `[@media(hover:hover)]`, etc.

Circular dependency detection (`index.ts:639`) prevents infinite loops in custom variant definitions.

### 8.6 @apply Implementation (`apply.ts`)

The `@apply` directive is one of the most complex features. It works by:

1. Collecting all `@apply` directives in the AST.
2. For each directive, parsing the referenced utility classes.
3. Compiling each utility against the design system.
4. Inlining the resulting declarations at the `@apply` site.
5. Handling `!important` propagation.
6. Detecting and reporting circular `@apply` chains.

**Restrictions:**
- Cannot be used inside `@keyframes` blocks (`apply.ts:36`).
- Cannot reference unknown utilities (`apply.ts:242`).
- Recursive `@apply` is supported but circular references are detected and rejected.

### 8.7 @import Resolution

The compiler resolves `@import` directives using a chain of resolvers provided by `@tailwindcss-node`:

1. **CSS resolver** — Resolves bare specifiers against `node_modules` with CSS-specific extensions (`.css`).
2. **ESM resolver** — Resolves with ESM conditions (`import`, `module`).
3. **CJS resolver** — Fallback to CommonJS resolution (`require`, `main`).

All resolvers are built on `enhanced-resolve` with appropriate configuration. Resolution respects `NODE_PATH` environment variable for additional search paths.

URL rewriting ensures that relative URLs in imported CSS files are adjusted relative to the output file, not the source file.

### 8.8 Module Reference

#### `packages/tailwindcss` — Core Compiler

| File | Purpose |
|---|---|
| `index.ts` | Main entry: `compile()`, `compileAst()`, `__unstable__loadDesignSystem()`. Design system initialization, plugin loading, variant/utility registration. |
| `css-parser.ts` | Custom CSS parser producing `AstNode[]`. Handles all Tailwind at-rules. |
| `ast.ts` | AST node type definitions and manipulation utilities. |
| `theme.ts` | `Theme` class — CSS custom property store with namespace resolution. |
| `candidate.ts` | Candidate parsing — converts class strings to structured `Candidate` objects. |
| `apply.ts` | `@apply` directive expansion with circular reference detection. |
| `utilities.ts` | Built-in utility registration (all core utilities). |
| `variants.ts` | Built-in variant registration (pseudo-classes, responsive, dark, etc.). |
| `css-functions.ts` | `--theme()`, `--spacing()`, `--alpha()` function resolution. |
| `source-maps.ts` | Source map generation and manipulation using `source-map-js`. |
| `compat/` | v3 compatibility layer: plugin API shim, config resolution. |
| `intellisense.ts` | IntelliSense support: class list generation, completion data. |
| `preflight.css` | CSS reset/normalize (Preflight). |
| `theme.css` | Default theme values as CSS custom properties. |
| `utilities.css` | Utility layer entry point. |
| `index.css` | Main CSS entry: imports preflight + theme + utilities. |

#### `packages/@tailwindcss-node` — Node.js Integration

| File | Purpose |
|---|---|
| `src/compile.ts` | `compile()` wrapper that integrates module resolution, URL rewriting, and optimization. Three resolver types: CSS, ESM, CJS. |
| `src/optimize.ts` | lightningcss integration for minification and transforms. |
| `src/env.ts` | `DEBUG` environment variable check. |
| `src/urls.ts` | URL rewriting for `@import`-ed CSS files. |
| `src/source-maps.ts` | Source map chain management. |

#### `packages/@tailwindcss-cli` — CLI Tool

| File | Purpose |
|---|---|
| `src/index.ts` | Entry point, argument parsing via `mri`. Command dispatch. |
| `src/commands/build/index.ts` | `build` command: compile CSS, write output, optional watch mode. |
| `src/commands/canonicalize/index.ts` | `canonicalize` command: deterministic CSS sorting. |

#### `packages/@tailwindcss-postcss` — PostCSS Plugin

| File | Purpose |
|---|---|
| `src/index.ts` | PostCSS plugin factory. LRU cache, incremental rebuild logic, AST conversion between PostCSS and internal formats. |

#### `packages/@tailwindcss-vite` — Vite Plugin

| File | Purpose |
|---|---|
| `src/index.ts` | Vite plugin factory. Two-step scan/generate architecture. HMR handling. Vite Environment API support for v7+. |

#### `packages/@tailwindcss-webpack` — Webpack Loader

| File | Purpose |
|---|---|
| `src/index.ts` | Webpack loader with LRU cache (max 50), mtime invalidation, CSS Modules detection. Quick bail check for non-Tailwind CSS files. |

#### `packages/@tailwindcss-browser` — Browser Build

| File | Purpose |
|---|---|
| `src/index.ts` | In-browser compiler. Watches `<style type="text/tailwindcss">` elements. MutationObserver on class attributes, new elements, new stylesheets. Queue-based build system (full/incremental). |

#### `packages/@tailwindcss-oxide` — N-API Bindings

| File | Purpose |
|---|---|
| `src/index.ts` | `Scanner` class TypeScript types. Platform binary loading with fallback. |
| Native binaries | Platform-specific `.node` files for 12 targets. |

#### `packages/@tailwindcss-upgrade` — Migration Tool

| File | Purpose |
|---|---|
| `src/index.ts` | Entry point, project detection, migration orchestration. |
| `src/codemods/css/` | CSS-level codemods: directives, imports, layers, @apply, theme-to-var, preflight, variants. |
| `src/codemods/template/` | Template-level codemods: candidates, arbitrary values/variants, legacy classes, prefix migration. |
| `src/codemods/js/` | JS config migration to CSS @theme. |
| `src/codemods/postcss/` | PostCSS config updates. |

#### `crates/oxide` — Rust Extraction Engine

| Module | Purpose |
|---|---|
| `src/lib.rs` | Public API: `Scanner` struct, `scan()`, `scan_files()`, `files()`, `globs()`. |
| `src/scanner/` | State machine implementations: `CandidateMachine`, `UtilityMachine`, `VariantMachine`, `NamedUtilityMachine`, `NamedVariantMachine`, `ArbitraryPropertyMachine`, `ArbitraryValueMachine`, `ArbitraryVariableMachine`, `CssVariableMachine`, `ModifierMachine`, `StringMachine`. |
| `src/pre_processors/` | Language-specific pre-processors for Clojure, Elixir, Haml, JSON, Markdown, Pug, Razor, Ruby, Rust, Slim, Svelte, Vue. |
| `src/glob.rs` | Glob pattern matching with hoisting optimization. |
| `src/fast_skip.rs` | SIMD-optimized whitespace skipping. |
| `src/cursor.rs` | Byte cursor for state machine input. |

#### `crates/node` — N-API Bridge

| Module | Purpose |
|---|---|
| `src/lib.rs` | napi-rs bindings. `Scanner` class exposed to Node.js. Uses `rayon` for parallel file scanning. |

#### `crates/ignore` — Gitignore Matching

| Module | Purpose |
|---|---|
| `src/lib.rs` | `.gitignore` pattern matching engine. Parallel directory walker. Forked from ripgrep's `ignore` crate. |

#### `crates/classification-macros` — Proc Macros

| Module | Purpose |
|---|---|
| `src/lib.rs` | `#[bytes(...)]` and `#[bytes_range(...)]` proc macros for generating byte lookup tables used by the scanner state machines. |

### 8.9 Compilation Pipeline Detail

The full compilation pipeline from CSS input to CSS output:

```
1. CSS Input String
   │
2. ├─► CSS Parser (css-parser.ts)
   │   └─► AstNode[]
   │
3. ├─► @import Resolution (@tailwindcss-node/compile.ts)
   │   └─► Recursive: resolve path → read file → parse → inline AST
   │
4. ├─► Design System Initialization (index.ts)
   │   ├─► Process @theme → populate Theme
   │   ├─► Process @plugin → load JS, register utilities/variants
   │   ├─► Process @config → load JS config, merge
   │   ├─► Process @variant → register custom variants
   │   ├─► Process @utility → register custom utilities
   │   ├─► Process @source → configure oxide Scanner globs
   │   └─► Register built-in utilities + variants
   │
5. ├─► Oxide Scan (via Scanner.scan())
   │   └─► candidate strings[]
   │
6. ├─► build(candidates) called
   │   ├─► Parse candidates → Candidate[]
   │   ├─► Resolve each Candidate against DesignSystem
   │   ├─► Apply variants (outside-in wrapping)
   │   ├─► Expand @apply directives
   │   └─► Produce final AstNode[]
   │
7. ├─► Serialize AST → CSS string
   │
8. ├─► Source map generation (optional)
   │
9. └─► lightningcss optimization (optional, via @tailwindcss-node)
        ├─► Minification
        ├─► Vendor prefixing
        ├─► @property polyfill
        └─► Final CSS output
```

### 8.10 Code Patterns and Conventions

**State machine pattern (Rust oxide):**

Every scanner machine implements a common interface: accept a byte cursor, advance through states, and return either a matched span or a rejection. Machines are composable — `CandidateMachine` dispatches to child machines based on the first few bytes. This avoids backtracking and keeps extraction O(n) in file size.

**Bitflag feature detection (TypeScript):**

The `Features` and `Polyfills` enums use bitwise operations for zero-cost feature detection during compilation. The compiler checks `features & Features.AtApply` to decide whether to run the @apply expansion pass, avoiding unnecessary work.

**LRU caching (PostCSS, Webpack):**

Both the PostCSS plugin and Webpack loader use LRU caches to avoid recompilation. The PostCSS cache uses `@alloc/quick-lru` (unbounded by default). The Webpack loader caps at 50 entries. Cache keys are derived from CSS content hashes plus file modification times.

**Atomic incremental builds:**

The `build()` function returned by `compile()` is designed to be called repeatedly with growing candidate sets. Internally, it tracks which candidates have already been compiled and only processes new ones. This is the foundation of incremental rebuilds in all integrations.

**Module resolution cascade:**

The triple-resolver pattern in `@tailwindcss-node/compile.ts` (CSS → ESM → CJS) ensures compatibility with the full npm ecosystem. CSS files use `style` and `css` conditions; ESM uses `import` and `module`; CJS uses `require` and `main`. This handles edge cases like packages that only export CJS or use non-standard fields.

---

## 9. Integration Points

### 9.1 Plugin API

Tailwind CSS v4 supports JavaScript/TypeScript plugins loaded via `@plugin`:

```css
@plugin "./my-plugin.ts";
```

```typescript
// my-plugin.ts
import plugin from "tailwindcss/plugin";

export default plugin(function ({ addUtilities, addVariant, matchUtilities, theme }) {
  addUtilities({
    ".content-auto": { "content-visibility": "auto" },
  });

  matchUtilities(
    { "tab": (value) => ({ "tab-size": value }) },
    { values: theme("tabSize") }
  );

  addVariant("hocus", "&:hover, &:focus");
});
```

> [!TIP]
> Plugins loaded via `@plugin` are resolved relative to the CSS file, not the project root. Use `@config` if you need to load a full v3-style configuration object with plugin arrays.

### 9.2 IntelliSense Integration

The `__unstable__loadDesignSystem()` export provides everything the Tailwind CSS IntelliSense VS Code extension needs:

- Complete list of registered utilities with their CSS output.
- Complete list of registered variants with their selector transformations.
- Full theme value map for autocomplete suggestions.
- Candidate validation for diagnostics.

### 9.3 PostCSS Ecosystem

The `@tailwindcss/postcss` plugin operates as a standard PostCSS plugin and can be composed with other PostCSS plugins:

```js
module.exports = {
  plugins: {
    "postcss-import": {},         // Runs before Tailwind
    "@tailwindcss/postcss": {},   // Tailwind compilation
    "autoprefixer": {}            // Runs after (usually redundant — lightningcss handles this)
  }
};
```

> [!IMPORTANT]
> Unlike v3, Tailwind CSS v4's PostCSS plugin handles `@import` resolution internally. Using `postcss-import` alongside `@tailwindcss/postcss` can cause double-resolution issues. Remove `postcss-import` unless you have non-Tailwind CSS files that need it.

### 9.4 Build Tool Integration Matrix

| Feature | CLI | PostCSS | Vite | Webpack | Standalone | Browser |
|---|---|---|---|---|---|---|
| Full compilation | Yes | Yes | Yes | Yes | Yes | Yes |
| Incremental rebuild | Via watch | Yes | Yes | Yes | Via watch | Yes |
| HMR | No | Via PostCSS | Yes (native) | Via loader | No | Yes (DOM) |
| Source maps | Yes | Yes | Yes | Yes | Yes | No |
| Minification | `--minify` | `optimize.minify` | Auto (prod) | `optimize.minify` | `--minify` | No |
| Plugin support | Yes | Yes | Yes | Yes | Yes (bundled) | No |
| CSS Modules | No | No | Via Vite | Yes | No | No |
| `@source` | Yes | Yes | Yes | Yes | Yes | No |
| `@config` | Yes | Yes | Yes | Yes | Yes (bundled) | No |
| Watch mode | `--watch` | Via PostCSS | Dev server | Dev server | `--watch` | MutationObserver |

### 9.5 Testing Strategy

The project uses vitest for unit and integration tests and Playwright for browser E2E tests.

**Test organization:**

```
packages/tailwindcss/
  __tests__/         Core compiler tests
integrations/
  cli/               CLI integration tests
  postcss/           PostCSS plugin tests
  vite/              Vite plugin tests
  webpack/           Webpack loader tests
  upgrade/           Migration tool tests
```

**Running tests:**

```bash
# Unit tests (vitest)
pnpm test

# Specific package
pnpm --filter tailwindcss test

# Integration tests
pnpm --filter @tailwindcss/integrations test

# Rust tests
cargo test --workspace
```

**Test patterns:**
- Compiler tests assert CSS output for given input CSS + candidate lists.
- Integration tests spin up real build tool processes and verify output files.
- Oxide tests verify candidate extraction against known inputs.
- Upgrade tests verify codemod transformations against before/after fixtures.

### 9.6 Build System

**TypeScript packages** are built with `tsup` (esbuild-based bundler):

```bash
pnpm build          # Build all packages via turbo
pnpm --filter tailwindcss build  # Build specific package
```

**Rust crates** are built with Cargo:

```bash
cargo build --release --workspace    # Build all crates
cargo build -p oxide --release       # Build oxide only
```

**N-API binaries** are built via napi-rs:

```bash
cd packages/@tailwindcss-oxide
pnpm build           # Builds native binary for current platform
```

**Turborepo** manages the build graph:
- `turbo.json` defines task dependencies (e.g., `build` depends on upstream `build`).
- Turbo caches build outputs — rebuilds only what changed.
- Remote caching can be enabled for CI.

**Standalone binary:**

```bash
cd packages/@tailwindcss-standalone
bun build ./src/index.ts --compile --target=bun-linux-x64 --outfile=tailwindcss
```

### 9.7 Contributing Workflow

```bash
# Clone and setup
git clone https://github.com/tailwindlabs/tailwindcss.git
cd tailwindcss
pnpm install
cargo build --workspace

# Development
pnpm dev              # Watch mode for all packages
pnpm test             # Run tests
pnpm format           # Prettier formatting

# Before submitting
pnpm build            # Full build
pnpm test             # Full test suite
cargo test            # Rust tests
cargo clippy          # Rust linting
```

### 9.8 Known Issues

| Issue | Description | Workaround |
|---|---|---|
| #19863 | Oxide scanner fails with certain arbitrary values | Use CSS custom properties instead of complex arbitrary values |
| #19930 | SOURCEMAP_BROKEN warnings in Nuxt/Vite setups | Source map chain breaks in multi-plugin PostCSS setups. Reduce PostCSS plugin chain. |
| #17958 | Missing lightningcss native module | Reinstall with `npm rebuild` or use a supported platform |
| #18540 | CLI watch mode fails with Docker bind mounts | Use volume mounts or polling-based watcher |
| #19893 | `module.register()` deprecation warning | Node.js loader API change. Cosmetic warning, no functional impact. |
| #15806 | Missing oxide native module on Linux ARM | Ensure `@tailwindcss/oxide-linux-arm64-gnu` (or musl variant) is installed. Use standalone binary as fallback. |

### 9.9 Version Compatibility

| Tailwind CSS | Node.js | PostCSS | Vite | Webpack |
|---|---|---|---|---|
| 4.0.x | 18+ | 8.x | 5.x, 6.x | 5.x |
| 4.1.x | 18+ | 8.x | 5.x, 6.x | 5.x |
| 4.2.x | 18+ | 8.x | 5.x, 6.x, 7.x | 5.x |

> [!NOTE]
> Vite 7 support was added in v4.2.x via the Vite Environment API. The plugin detects the Vite version at runtime and uses the appropriate API surface.

### 9.10 Upgrade Path: v3 to v4

The architectural changes from v3 to v4 are substantial:

| Aspect | v3 | v4 |
|---|---|---|
| Configuration | `tailwind.config.js` | CSS `@theme` blocks |
| Plugin system | JS config `plugins: []` | CSS `@plugin` directive |
| Content scanning | `content: ['./src/**/*.html']` | Automatic (oxide + `@source`) |
| CSS processing | PostCSS-only | Standalone compiler + integrations |
| Class extraction | JavaScript regex | Rust state machines |
| Theme access | `theme()` function | CSS custom properties (`var(--color-*)`) |
| Dark mode | `darkMode: 'class'` | `@variant dark (...)` |
| Prefixes | `prefix: 'tw-'` | CSS-level prefixing |
| Important | `important: true` | CSS-level `@layer` ordering |

The `@tailwindcss/upgrade` tool automates most of this migration. Run it in the project root and review the changes:

```bash
npx @tailwindcss/upgrade
git diff  # Review all changes before committing
```

> [!TIP]
> The upgrade tool is conservative — it preserves functionality over style. After running it, manually review the generated `@theme` block for opportunities to simplify (e.g., removing values that match the default theme).

---

_Generated May 2026 from tailwindlabs/tailwindcss at 5a835e1. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
