CLI Reference
Purpose and Scope
The @tailwindcss/cli package is the command-line entry point for running Tailwind CSS outside a framework integration. It is the path described by the official Tailwind CLI installation flow: install tailwindcss and @tailwindcss/cli, import Tailwind from a CSS entry file, then run the CLI to scan source files and write a compiled CSS file. In repository terms, the package publishes a tailwindcss binary, parses terminal arguments, routes subcommands, renders help text, and delegates CSS builds or candidate canonicalization to command modules. This page focuses on that public command surface and the source files that define it.
Sources: packages/@tailwindcss-cli/package.json, packages/@tailwindcss-cli/src/index.ts
The CLI should be read as a thin orchestration layer rather than the whole compiler. The package depends on tailwindcss, @tailwindcss/node, @tailwindcss/oxide, @parcel/watcher, enhanced-resolve, mri, and picocolors, which signals its role as a Node-distributed binary that can invoke the Tailwind compiler, watch files, parse arguments, and format terminal output. The actual npm package exposes only the built executable through the bin field and its package metadata through exports, so consumers should treat the terminal command as the supported public interface rather than importing internal TypeScript modules.
Sources: packages/@tailwindcss-cli/package.json
Relevant Source Files
packages/@tailwindcss-cli/package.json— declares the npm package name@tailwindcss/cli, the publishedtailwindcssbinary at./dist/index.mjs, build scripts, package files, and runtime dependencies used by the CLI.packages/@tailwindcss-cli/src/index.ts— implements the executable entry point, root command routing, shared--helphandling, invalid command behavior, and delegation tobuildandcanonicalize.packages/@tailwindcss-cli/src/commands/help/index.ts— formats help output, including the header, invalid command notice, usage wrapping, option alignment, aliases, defaults, and allowed values.packages/@tailwindcss-cli/src/commands/canonicalize/index.ts— implements thetailwindcss canonicalizecommand, its options, command-line result contract, streaming mode, and design-system-backed candidate processing.packages/@tailwindcss-cli/src/utils/args.ts— defines the CLI argument schema type and runtime parsing behavior built onmri, including aliases, defaults, positional arguments, and value conversion.
Command Entry Point and Routing
The executable starts in src/index.ts with a Node shebang, imports the shared args utility, and loads command modules for build, canonicalize, and help. The package-level bin mapping turns that file’s built output into the tailwindcss command when installed. Users may therefore run examples such as npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css --watch, while the entry point sees only process.argv.slice(2) and decides whether those arguments represent the root build flow, an explicit subcommand, or a request for help.
Sources: packages/@tailwindcss-cli/package.json, packages/@tailwindcss-cli/src/index.ts
Routing is intentionally conservative. If the first argument is build, the entry point reparses the remaining arguments with build options plus shared options, shows build-specific help when appropriate, and otherwise calls build.handle(flags). If the first argument is canonicalize, it calls canonicalize.runCommandLine({ argv: argv.slice(1) }), writes returned stdout and stderr strings to the corresponding process streams, and assigns process.exitCode. If there is no subcommand, the CLI treats root flags as the build command unless the terminal context and flags indicate help. This preserves the familiar short command form while still allowing named subcommands.
Sources: packages/@tailwindcss-cli/src/index.ts, packages/@tailwindcss-cli/src/commands/canonicalize/index.ts
Invalid command handling is part of the root router, not a later command failure. When the first argument exists and does not start with -, and it is not one of the recognized subcommands, the entry point renders root help with an invalid value and exits with status code 1. By contrast, help conditions exit successfully. This distinction matters for scripts: tailwindcss --help and terminal-only empty invocation are informational, while tailwindcss unknown is a usage error that should fail automation.
Sources: packages/@tailwindcss-cli/src/index.ts, packages/@tailwindcss-cli/src/commands/help/index.ts
Argument Parser Contract
All command option definitions use the Arg shape from utils/args.ts. An option key must be a long flag beginning with --, and each definition declares a runtime type, a human-readable description, and optional alias, default, and values. The type list is deliberately explicit: booleans, numbers, strings, and union-like combinations such as boolean | string are converted at runtime because TypeScript’s static types do not exist after compilation. This lets command modules describe options once and receive a typed result object with positional arguments in _.
Sources: packages/@tailwindcss-cli/src/utils/args.ts
The parser uses mri to read raw arguments, then normalizes important edge cases before applying command definitions. A bare - is temporarily replaced with a sentinel value and restored after parsing, which allows commands to treat standard input or output markers as values instead of losing them to flag parsing. Repeated flags collapse to the last value. For every declared option, the parser starts with an explicit default, or uses false for booleans and null for other types. Aliases are checked before long flags, and long flags can override alias-derived values when both are provided.
Sources: packages/@tailwindcss-cli/src/utils/args.ts
This parser contract explains why command modules can be small and predictable. A flag absent from the command line still appears in the result, so command handlers do not need to repeatedly distinguish missing keys from falsey values. A positional class list, CSS filename, or other trailing input remains available under _. Command authors also get a consistent description format for help output because the same Arg metadata feeds both parsing and rendering. For users, this means the CLI accepts short aliases where defined, long flags everywhere, and value conversion according to the command’s declared option types.
Sources: packages/@tailwindcss-cli/src/utils/args.ts, packages/@tailwindcss-cli/src/commands/help/index.ts
Help Output and Renderer Behavior
Help output is generated by the help function in commands/help/index.ts. The entry point passes usage examples, options, and sometimes an invalid command label; the helper then emits a Tailwind header, an optional invalid command notice, a usage block, and an options block. It reads process.stdout.columns and falls back to 80, so usage lines can wrap to the current terminal width. The implementation imports renderer primitives named UI, header, highlight, indent, println, and wordWrap, making layout a shared terminal-rendering concern rather than ad hoc string concatenation in each command.
Sources: packages/@tailwindcss-cli/src/commands/help/index.ts, packages/@tailwindcss-cli/src/index.ts
Usage rendering is careful about readability. Each usage example is split into the command portion and bracketed option portion. The option portion is dimmed with picocolors, wrapped to fit the remaining width after indentation and command length, and then continuation lines are indented so they align with the options from the first line. When a later usage example needs multiple wrapped lines, the renderer inserts spacing to visually separate examples. Root help includes both root build usage, explicit tailwindcss build usage, and tailwindcss canonicalize [classes...], while build help narrows the usage list to the build command.
Sources: packages/@tailwindcss-cli/src/commands/help/index.ts, packages/@tailwindcss-cli/src/index.ts
Option rendering is also metadata-driven. The help function inspects all option definitions to calculate the maximum alias length and maximum option string length, then formats aliases, long flags, allowed values, descriptions, and defaults in aligned columns. Options that define values display those values inline as an allowed set, as seen in canonicalize --format[=text, json, jsonl] through the command metadata. The help function can render directly to the terminal, or collect lines when render is false; canonicalize uses that capability to return help as part of its structured command-line result.
Sources: packages/@tailwindcss-cli/src/commands/help/index.ts, packages/@tailwindcss-cli/src/commands/canonicalize/index.ts
Canonicalize Command Reference
tailwindcss canonicalize is a developer-facing command for normalizing candidate groups, where a candidate is a class-like Tailwind token and a group is the input string being processed. The command exports usage(), options(), runCommandLine(), streamStdin(), and supporting result types. Its simple usage is tailwindcss canonicalize [classes...]; additional forms document --css input.css for loading a project-specific design system and --stream [--css input.css] for line-by-line standard input. Internally, it loads a design system through __unstable__loadDesignSystem from @tailwindcss/node and imports comparison and segmentation utilities from the core Tailwind package.
Sources: packages/@tailwindcss-cli/src/commands/canonicalize/index.ts
| Name | Kind | Behavior |
|---|---|---|
tailwindcss canonicalize [classes...] | command | Canonicalizes one or more candidate groups supplied as positional arguments. |
--css | string option | CSS entry file used to load the Tailwind design system; defaults to an in-memory @import "tailwindcss"; entry according to the option description. |
--format | string option | Selects output format, defaulting to text; allowed values are text, json, and jsonl. |
--stream | boolean option | Reads candidate groups from stdin line by line and writes each result to stdout. |
--help, -h | shared option | Returns canonicalize help without treating missing candidate groups as an error. |
The command-line result contract is explicit: runCommandLine() resolves to { exitCode, stdout, stderr }. That makes it easy for the root entry point to write streams and set process status without duplicating command logic. If help is requested, the result has exit code 0, help text in stdout, and empty stderr. If no positional inputs are supplied, the command attempts to read candidate groups from stdin unless stdin is a TTY; an empty final input set becomes a usage error. Runtime exceptions are caught and converted into exit code 1 with the error message in stderr.
Sources: packages/@tailwindcss-cli/src/commands/canonicalize/index.ts, packages/@tailwindcss-cli/src/index.ts
Streaming mode is distinct from buffered mode. With --stream, the command loads the design system once, creates a readline interface over the provided readable stream, and processes each incoming line as an independent candidate group. In text format it writes the canonicalized output followed by a newline. In jsonl format it writes one serialized result object per line. In json format it begins an array and then writes result objects into that array, preserving a single JSON document across the stream. This mode is useful for tooling that needs to feed many class lists through the same design system without restarting the command for every input.
Sources: packages/@tailwindcss-cli/src/commands/canonicalize/index.ts
Practical Usage Patterns
For ordinary application builds, the official installation sequence remains the clearest starting point: install tailwindcss and @tailwindcss/cli, add @import "tailwindcss"; to a CSS entry file, then run the binary with an input file, output file, and watch flag. The entry point supports the short root form used by the docs because unrecognized flag-leading invocations fall through to build handling. The explicit tailwindcss build form is available when a script prefers named commands, and both forms share the same build option metadata through build.options().
Sources: packages/@tailwindcss-cli/src/index.ts
npm install tailwindcss @tailwindcss/cli
npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css --watchFor command authors and contributors, add new CLI behavior by following the existing separation of concerns. Define option metadata with Arg, parse through args(), return or print through a command-level boundary, and let the root entry point handle top-level routing. If the command needs terminal documentation, feed the same option metadata into help() so aliases, defaults, allowed values, and wrapping stay consistent with the rest of the CLI. If the command needs script-friendly operation, prefer a result object like canonicalize so tests and callers can inspect stdout, stderr, and exit code without spawning a real process.
Sources: packages/@tailwindcss-cli/src/utils/args.ts, packages/@tailwindcss-cli/src/commands/help/index.ts, packages/@tailwindcss-cli/src/commands/canonicalize/index.ts
Next Steps
Read the installation-oriented Tailwind CLI page when you want the shortest path from an empty project to a compiled CSS file. Read the tailwindcss Package API and Node API pages when you need to understand what the CLI delegates to for compilation, dependency tracking, optimization, or design-system loading. Read the Upgrade Tool page separately: it is also a command-line workflow in this monorepo, but it is implemented in the @tailwindcss/upgrade package rather than in @tailwindcss/cli. For CLI changes, start with src/index.ts, then inspect the command module and parser contract before changing help text or option behavior.
Sources: packages/@tailwindcss-cli/src/index.ts, packages/@tailwindcss-cli/src/utils/args.ts