tailwindlabs/tailwindcss
@tailwindcss/cli and @tailwindcss/standalone
Active contributors: Robin, Philipp, Jordan
Purpose
@tailwindcss/cli is the tailwindcss command-line build tool. It reads input CSS, scans the project for class candidates, runs the compiler, and writes output CSS. @tailwindcss/standalone repackages the same CLI as a single native binary built with Bun, with several first-party plugins (forms, typography, aspect-ratio) bundled in.
Directory layout
packages/@tailwindcss-cli/
├── package.json # bin: tailwindcss → ./dist/index.mjs
├── README.md
├── tsconfig.json
├── tsup.config.ts
└── src/
├── index.ts # CLI entry point and command router
├── commands/
│ ├── build/
│ │ ├── index.ts # `tailwindcss build`
│ │ └── utils.ts
│ ├── canonicalize/
│ │ ├── index.ts # `tailwindcss canonicalize`
│ │ ├── canonicalize.test.ts
│ │ └── fixtures/
│ └── help/
│ └── index.ts
└── utils/
├── args.ts # mri-based argument parser
├── disposables.ts # cleanup helpers for watchers
└── renderer.ts # printing / formatting / colors
packages/@tailwindcss-standalone/
├── package.json # bundles @tailwindcss/cli + plugins
├── scripts/
│ └── build.ts # Bun build script
└── src/
├── index.ts # Re-exports CLI + plugin discovery
└── types.d.tsCommands
The router in packages/@tailwindcss-cli/src/index.ts dispatches three commands:
| Command | Module | Purpose |
|---|---|---|
tailwindcss build |
packages/@tailwindcss-cli/src/commands/build/index.ts |
Compile CSS once or in watch mode. |
tailwindcss canonicalize |
packages/@tailwindcss-cli/src/commands/canonicalize/index.ts |
Print canonicalized class lists from stdin or files. |
tailwindcss --help |
packages/@tailwindcss-cli/src/commands/help/index.ts |
Usage screen. |
When called with no command, the CLI defaults to build.
tailwindcss build
Flags (defined in packages/@tailwindcss-cli/src/commands/build/index.ts):
| Flag | Type | Default | Notes |
|---|---|---|---|
--input, -i |
string | — | Input CSS file. If absent, reads from stdin. |
--output, -o |
string | - |
Output file or - for stdout. |
--watch, -w |
boolean / always |
false | Re-build on change. always keeps watching after stdin closes. |
--minify, -m |
boolean | false | Optimize + minify via Lightning CSS. |
--optimize |
boolean | false | Optimize without minifying. |
--cwd |
string | . |
Project base directory. |
--map |
boolean / string | false | Generate a source map. |
The build loop:
graph TD
A[Read input CSS] --> B[Setup Instrumentation]
B --> C[compile or compileAst]
C --> D[Construct Scanner from compiler.sources + root + cwd]
D --> E[scanner.scan or scanFiles]
E --> F[compiler.build candidates]
F --> G{shouldOptimize?}
G -->|yes| H[optimize via lightningcss]
G -->|no| I[skip]
H --> J[Write output]
I --> J
J --> K{watch?}
K -->|yes| L["@parcel/watcher subscribe"]
K -->|no| M[exit]
L -->|change| EWatch behavior comes from @parcel/watcher plus the Disposables helper in src/utils/disposables.ts — a small abstraction for "register a cleanup function, run all of them on shutdown."
tailwindcss canonicalize
Reads class lists from stdin or arguments and prints them in canonical form. Useful for testing or for scripted refactors. Implementation in commands/canonicalize/index.ts; the actual normalization is done by canonicalizeCandidate from the compiler (packages/tailwindcss/src/canonicalize-candidates.ts).
@tailwindcss/standalone
The standalone package wraps the CLI:
- It depends on
@tailwindcss/cliplus the official forms / typography / aspect-ratio plugins. - Its
src/index.tsperforms runtime resolution so the bundled binary can find the embedded plugins (nonode_modulesto look up). - The Bun build script (
scripts/build.ts) cross-compiles for every supported platform.
The package.json notes:
These binary packages must be included so Bun can build the CLI for all supported platforms. We also rely on Lightning CSS and Parcel being patched so Bun can statically analyze the executables.
That's why @tailwindcss/standalone lists per-platform @parcel/watcher-* and lightningcss-* packages as devDependencies — Bun needs concrete imports to embed.
Integration points
- Reads from
tailwindcss: the compiler is the data source forcompile()/compileAst()and thecanonicalizeCandidatefunction. It usestailwindcssdirectly (not via@tailwindcss/node). - Reads from
@tailwindcss/node: the build command importscompile,env,Instrumentation,optimize,toSourceMapfor Node-specific concerns. The CLI itself never importslightningcssormagic-stringdirectly. - Reads from
@tailwindcss/oxide: for theScannerclass used to find candidates. - Writes to:
process.stdout(or--outputfile); optionally a sourcemap file.
Entry points for modification
- Add a flag: edit
options()inpackages/@tailwindcss-cli/src/commands/build/index.tsand read it from theargsresult insidehandle(). - Add a command: create a new directory under
commands/with anindex.tsthat exportshandle()andoptions(). Register it inpackages/@tailwindcss-cli/src/index.ts's router. - Change watch debouncing or fan-out: the
@parcel/watchersubscription happens insidehandle()incommands/build/index.ts.
For Vite/PostCSS/Webpack equivalents see vite, postcss, webpack.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.