# Contributor handoff — tailwindlabs/tailwindcss

> Canonical page: https://codevetter.com/unpack/tailwindcss/agent-handoff

# Contributor handoff — tailwindlabs/tailwindcss

Scanned commit 41d9cae8e53378d16087fcf359eb785c2fd42ce4 (2026-09-08). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Read the core compiler before touching anything: `packages/tailwindcss/src/index.ts` (`parseCss` → `compileAst` → `compile`), then `design-system.ts` and `compile.ts`. Almost every behavioral change belongs in `packages/tailwindcss` or `crates/oxide`, not in the integration packages — those are thin and near-duplicative on purpose. Conventions are enforced mechanically: Prettier config lives inline in the root `package.json` (no semicolons, single quotes, 100 columns, organize-imports), and `pnpm lint` runs `prettier --check` plus `turbo lint` (which is `tsc --noEmit` per package). The project explicitly does not accept feature PRs without prior discussion, and does not accept any PR without tests.
- Read first, in order: `packages/tailwindcss/src/index.ts` (the at-rule walk and `build()` contract), `packages/tailwindcss/src/design-system.ts` (the `DesignSystem` type and its caches), `packages/tailwindcss/src/compile.ts` (candidate → AST + sorting), and `crates/oxide/src/scanner/mod.rs` (the scan lifecycle). — [packages/tailwindcss/src/index.ts](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/tailwindcss/src/index.ts) [packages/tailwindcss/src/design-system.ts](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/tailwindcss/src/design-system.ts) [packages/tailwindcss/src/compile.ts](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/tailwindcss/src/compile.ts) [crates/oxide/src/scanner/mod.rs](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/crates/oxide/src/scanner/mod.rs)
- Setup is `pnpm install`, `rustup default stable`, `rustup target add wasm32-wasip1-threads`, then `pnpm build`; the WASM target is mandatory because `@tailwindcss/oxide`'s `build` script always runs `build:wasm` after `build:platform`. — [.github/CONTRIBUTING.md#L3-L24](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/.github/CONTRIBUTING.md#L3-L24) [crates/node/package.json#L48-L56](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/crates/node/package.json#L48-L56)
- Day-to-day loop is `pnpm tdd` (Vitest watch with `--hideSkippedTests`); for browser or integration behavior you must run `pnpm build` first because both harnesses consume built artifacts. — [package.json#L34-L40](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/package.json#L34-L40) [.github/CONTRIBUTING.md#L26-L34](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/.github/CONTRIBUTING.md#L26-L34) [.github/CONTRIBUTING.md#L64-L82](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/.github/CONTRIBUTING.md#L64-L82)
- Before submitting: run `pnpm test` (cargo + vitest), `pnpm build && pnpm test:integrations`, `pnpm build && pnpm test:ui`, and `pnpm run lint`; `pnpm run format` auto-fixes style. — [.github/CONTRIBUTING.md#L52-L84](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/.github/CONTRIBUTING.md#L52-L84) [package.json#L26-L40](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/package.json#L26-L40)
- Code style is Prettier with `semi: false`, `singleQuote: true`, `printWidth: 100`, and `prettier-plugin-organize-imports`; `integrations/**/*.ts` additionally uses `prettier-plugin-embed` so embedded CSS/HTML template literals are formatted. — [package.json#L5-L25](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/package.json#L5-L25)
- Safe edit boundary: the core compiler must stay IO-free. Anything needing `fs`, module resolution, or Lightning CSS belongs in `@tailwindcss/node`, which is the only package allowed to be the bridge between core and the runtime. — [packages/tailwindcss/src/index.ts#L253-L281](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/tailwindcss/src/index.ts#L253-L281) [packages/@tailwindcss-node/src/compile.ts](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/%40tailwindcss-node/src/compile.ts)
- A change to utility or variant output almost always needs a snapshot update in `packages/tailwindcss/src/utilities.test.ts` or `variants.test.ts`, plus a check of `packages/tailwindcss/src/__snapshots__/`; these files are enormous, so target specific test names rather than running the whole suite. — [packages/tailwindcss/src/utilities.test.ts](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/tailwindcss/src/utilities.test.ts) [packages/tailwindcss/src/variants.test.ts](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/tailwindcss/src/variants.test.ts) [packages/tailwindcss/src/__snapshots__](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/tailwindcss/src/__snapshots__)
- Trap: output ordering is not alphabetical. It is governed by `GLOBAL_PROPERTY_ORDER` in `property-order.ts` combined with a BigInt variant bitmask; reordering that array silently reshuffles every generated stylesheet. — [packages/tailwindcss/src/property-order.ts](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/tailwindcss/src/property-order.ts) [packages/tailwindcss/src/compile.ts#L78-L112](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/tailwindcss/src/compile.ts#L78-L112)
- Trap: `process.env.NODE_ENV !== 'test'` gates both the license banner comment prepended in `compileAst` and the Lightning CSS warning output, so CSS produced under test differs from production output. — [packages/tailwindcss/src/index.ts#L700-L706](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/tailwindcss/src/index.ts#L700-L706) [packages/@tailwindcss-node/src/optimize.ts#L70-L78](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/%40tailwindcss-node/src/optimize.ts#L70-L78)
- Trap: the integration packages duplicate the same source-derivation block (`root === 'none'` / `root === null` / explicit root, concat `compiler.sources`). Changing that contract in core requires updating the CLI, Vite, PostCSS, webpack, and Turbopack call sites together. — [packages/@tailwindcss-cli/src/commands/build/index.ts#L285-L305](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/%40tailwindcss-cli/src/commands/build/index.ts#L285-L305) [packages/@tailwindcss-vite/src/index.ts#L410-L428](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/%40tailwindcss-vite/src/index.ts#L410-L428) [packages/@tailwindcss-postcss/src/index.ts#L207-L226](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/%40tailwindcss-postcss/src/index.ts#L207-L226) [packages/@tailwindcss-webpack/src/index.ts](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/%40tailwindcss-webpack/src/index.ts)
- Trap: Rust edits need `pnpm build` (or `pnpm --filter @tailwindcss/oxide build`) to regenerate the `.node` addon before JS tests see them; `turbo.json` declares the cross-crate `inputs` that make this cache correctly. — [turbo.json](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/turbo.json) [crates/node/package.json#L48-L56](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/crates/node/package.json#L48-L56)
- Debugging hook: set `DEBUG=1` (or `DEBUG=tailwindcss`) to enable the `Instrumentation` timers that bracket every phase — 'Setup compiler', 'Scan for candidates', 'Build CSS', 'Optimize CSS' — across the CLI, Vite, PostCSS, and loaders. — [packages/@tailwindcss-node/src/env.ts](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/%40tailwindcss-node/src/env.ts) [packages/@tailwindcss-node/src/instrumentation.ts](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/%40tailwindcss-node/src/instrumentation.ts) [packages/@tailwindcss-cli/src/commands/build/index.ts#L118-L128](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/packages/%40tailwindcss-cli/src/commands/build/index.ts#L118-L128)
- Debugging hook for the scanner: `crates/oxide/src/scanner/init_tracing.rs` gates `tracing` events behind a `SHOULD_TRACE` lazy static, logging both provided and optimized source entries at INFO level. — [crates/oxide/src/scanner/init_tracing.rs](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/crates/oxide/src/scanner/init_tracing.rs) [crates/oxide/src/scanner/mod.rs#L95-L115](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/crates/oxide/src/scanner/mod.rs#L95-L115)
- Process convention: PRs need a test plan and tests; feature PRs are likely to be closed without prior discussion in GitHub Discussions; adding `[ci-all]` to the PR body opts into the full Windows/macOS CI matrix. — [.github/CONTRIBUTING.md#L38-L50](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/.github/CONTRIBUTING.md#L38-L50) [.github/CONTRIBUTING.md#L86-L94](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/.github/CONTRIBUTING.md#L86-L94) [.github/workflows/ci.yml#L34-L42](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/.github/workflows/ci.yml#L34-L42)
- Do not hand-edit release plumbing: `scripts/version-packages.mjs`, `scripts/lock-pre-release-versions.mjs`, `scripts/release-channel.js`, and `scripts/pre-publish-optimizations.mjs` are driven by `prepare-release.yml`/`release.yml`, and npm trusted publishing validates the calling workflow filename. — [scripts/release-channel.js](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/scripts/release-channel.js) [scripts/version-packages.mjs](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/scripts/version-packages.mjs) [.github/workflows/release.yml#L228-L236](https://github.com/tailwindlabs/tailwindcss/blob/41d9cae8e53378d16087fcf359eb785c2fd42ce4/.github/workflows/release.yml#L228-L236)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
