tailwindlabs/tailwindcss
Tooling
Turborepo
turbo.json defines the task pipeline. The interesting wrinkle is the explicit task definition for @tailwindcss/oxide#build and @tailwindcss/oxide#dev:
{
"@tailwindcss/oxide#build": {
"dependsOn": ["^build"],
"outputs": ["./index.d.ts", "./index.js", "./*.node"],
"inputs": [
"./src/**/*",
"./build.rs",
"./package.json",
"./Cargo.toml",
"./.cargo/config.toml",
"../oxide/src/**/*",
"../oxide/Cargo.toml",
"../Cargo.toml",
"../package.json",
],
},
}This is needed because the @tailwindcss/oxide npm package (in crates/node/) builds via build.rs, which calls cargo build — Turborepo can't infer the Rust source's input/output graph automatically.
globalPassThroughEnv: ["RUSTUP_HOME"] lets the Rust build pick up a custom rustup install path when CI runs.
tsup
Every TypeScript package uses tsup for bundling. Each package has a tsup.config.ts that configures entry points, formats (ESM/CJS), and dts (.d.ts emission). Tsup invokes esbuild under the hood.
The tsup-node binary (which is what the build scripts call) is just tsup with Node-specific defaults.
@tailwindcss/standalone is the exception — it builds with Bun instead of tsup, see packages/@tailwindcss-standalone/scripts/build.ts.
Vitest
Vitest is the test runner everywhere. The root vitest.config.ts defines a workspace with two projects:
node— covers most files.jsdom— used for the browser bundle's tests.
Each package can override with its own vitest.config.ts (e.g. packages/tailwindcss/vitest.config.ts).
Common flags:
pnpm vitest # interactive
pnpm vitest run # single pass
pnpm vitest run packages/tailwindcss # only that package
pnpm vitest run -- -u # update snapshots
pnpm vitest bench # run *.bench.tsCargo
The Cargo.toml workspace at the repo root pulls in crates/*. The release profile is configured for LTO:
[profile.release]
lto = trueThat keeps the published @tailwindcss/oxide binary small.
The crates/node/.cargo/config.toml (visible in the directory listing but not shown here) selects the right NAPI target per platform.
Bun (for @tailwindcss/standalone)
The standalone CLI is built with Bun. Build script: packages/@tailwindcss-standalone/scripts/build.ts. It produces native binaries for every supported platform by depending on per-platform @parcel/watcher-* and lightningcss-* packages and letting Bun statically link them.
Bun's static analyzer can't see through certain dynamic imports, which is why patches/ contains:
@parcel/watcher@2.5.1.patchlightningcss@1.32.0.patch
These patches make those modules statically analyzable.
Lightning CSS
lightningcss is used for the final optimization pass in @tailwindcss/node (packages/@tailwindcss-node/src/optimize.ts). Adapters that opt into optimize: true (or default to it in production) hand the compiler's output to Lightning CSS for minification, vendor prefixing, and modern syntax lowering.
lightningcss is not a runtime dependency of the compiler. It only runs in the Node-side adapters.
jiti
jiti is used by @tailwindcss/node to load JavaScript config files (tailwind.config.js) and plugins on-the-fly without a separate compile step. It supports TypeScript configs out of the box. See packages/@tailwindcss-node/src/compile.ts.
enhanced-resolve
enhanced-resolve (the same module Webpack uses internally) backs the loadStylesheet and loadModule resolvers in @tailwindcss/node and @tailwindcss/cli. This is how @import 'tailwindcss', @plugin '…', and @config '…' find their files when not running under a bundler.
Parcel watcher
@parcel/watcher is the file-system watcher used by @tailwindcss/cli (packages/@tailwindcss-cli/src/commands/build/index.ts) and the standalone CLI. Vite and Webpack provide their own watchers, so they don't use it.
CI workflows
Four workflow files in .github/workflows/:
ci.yml— runs lint and unit tests on every PR.integration-tests.yml— runs the integration suite. Triggered on PRs that opt-in via[ci-all]and onmain.prepare-release.yml— orchestrates the release-prep PR.release.yml— publishes to npm.
The release workflows are large (12K and 13K bytes respectively) because they handle Rust binary cross-compilation, NPM tarball assembly, and the standalone CLI builds.
scripts/
A handful of one-shot scripts:
pack-packages.mjs— produces tarballs for integration tests.version-packages.mjs— bumps versions for release.lock-pre-release-versions.mjs— pins pre-release versions before publish.pre-publish-optimizations.mjs— strips dev-only code paths before publish.release-channel.js— determines whether a release islatest,next, orinsiders.release-notes.mjs— generates the release notes payload.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.