Tailwind 5,202 never parses your HTML or runs your JavaScript. It reads source files as plain text, extracts anything that could be a class name, and generates CSS only for tokens it recognizes. Version 4's engine, Oxide (previewed in 2023), puts the expensive, parallel work in Rust and keeps the extensible core in TypeScript.

Scanning
The scanner walks your project on several threads (Rust's rayon crate), skipping .gitignored paths and binary files (adjust with @source, Class Detection (@source)). State machines in the repository's crates/oxide folder recognize the shape of a candidate: variants, a utility name, an optional /modifier and bracketed arbitrary values; pre-processors first adapt syntaxes such as Pug 352,080 , Haml and Vue 5,482 . Nothing is evaluated, so ` bg-${color}-500 ` is never found: always write complete class names.
Generating
The compiler parses your CSS with its own parser (over twice as fast as PostCSS 238,379 , by Tailwind's measurement), matches each candidate against registered utilities and variants, and silently drops the rest. The listing drives all three stages through @tailwindcss/oxide and @tailwindcss/node, the internal packages behind the Vite 25,978 plugin, PostCSS plugin and CLI. Their APIs change between minor versions, so use them only to learn or debug.
// src/card.html contains: <p class="p-4 hover:bg-sky-100">Price: 12 dollars</p>
import { Scanner } from '@tailwindcss/oxide'
import { compile, optimize } from '@tailwindcss/node'
const scanner = new Scanner({ sources: [{ base: 'src', pattern: '**/*', negated: false }] })
const candidates = scanner.scan() // 1. scan (Rust)
console.log(candidates)
const input = '@import "tailwindcss/theme.css" layer(theme);\n' +
'@import "tailwindcss/utilities.css" layer(utilities);'
const compiler = await compile(input, { base: import.meta.dirname, onDependency() {} })
const css = compiler.build(candidates) // 2. generate (TypeScript)
console.log(optimize(css).code) // 3. optimize (Lightning CSS)[ 'class', 'dollars', 'hover:bg-sky-100', 'p-4' ]
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
@layer theme {
:root, :host {
--color-sky-100: oklch(95.1% .026 236.824);
--spacing: .25rem;
}
}
@layer utilities {
.p-4 {
padding: calc(var(--spacing) * 4);
}
@media (hover: hover) {
.hover\:bg-sky-100:hover {
background-color: var(--color-sky-100);
}
}
}class and dollars were candidates but produced nothing. Only the theme variables in use were emitted, p-4 multiplies one --spacing variable, and hover: sits inside @media (hover: hover) so a tap on a touch screen leaves no sticky hover.
Optimizing
Lightning CSS, Devon Govett's Rust CSS transformer (MPL-2.0, Pre- and Postprocessors), flattens nesting, adds prefixes and lowers syntax for Tailwind's targets (Chrome 111 1 , Safari 16.4 10 , Firefox 128 555 ), then runs a second pass to merge adjacent rules. The payoff is speed: Tailwind's v4.0 benchmark cut a full build from 378 ms to 100 ms, and a rebuild with no new classes from 35 ms to 192 µs.