Open-Source Wikis

/

Tailwind CSS

/

Fun facts

tailwindlabs/tailwindcss

Fun facts

The first commit was on a Thursday afternoon in 2017

421c1b0d"Init" — landed on 2017-07-20. The very next commits are titled "Normalize spacing (to 2 spaces)." and "Remove stripe elements styles.", which suggests the project started life as a CSS file extracted from somewhere else (probably a Stripe-themed admin template, since stripe-elements is mentioned by name) and only later became a framework.

The single biggest source file in the repo is 7,800 lines of utility definitions

packages/tailwindcss/src/utilities.ts weighs in at roughly 7,800 lines. It registers every built-in utility — flex, grid, bg-*, text-*, border-*, the lot — plus their bare-value, fractional, and arbitrary-value variants. Its accompanying test file (utilities.test.ts) is even larger at ~26,000 lines and is the single largest test file in the repo.

In second place: canonicalize-candidates.ts (~3,300 lines), which encodes the rules that turn a list of class names into their preferred shorthand (e.g. px-4 py-4p-4, border-t-2 border-r-2 border-b-2 border-l-2border-2).

The codebase has its own state-machine cookbook

The Rust extractor in crates/oxide/src/extractor/ is built out of ~13 small state machines that share a single Cursor. Each handles one shape:

  • candidate_machine.rs — top-level driver
  • named_utility_machine.rsbg-red-500-style names
  • named_variant_machine.rshover:-style prefixes
  • arbitrary_value_machine.rs[#fff]-style values
  • arbitrary_property_machine.rs[--my-var:1]
  • arbitrary_variable_machine.rs(--var) shorthand
  • modifier_machine.rs/50, /[…]
  • css_variable_machine.rs — bare var(--foo) references
  • string_machine.rs, utility_machine.rs, variant_machine.rs, boundary.rs, bracket_stack.rs, machine.rs

The shared machine.rs defines the trait, and mod.rs (~1,200 lines) glues it all together. Each machine is small enough to read end-to-end, which is intentional: contributors can fix or extend a single shape without touching the rest of the extractor.

A Rust crate is vendored in source

crates/ignore/ is a near-verbatim copy of BurntSushi/ripgrep's ignore crate. It carries its own LICENSE-MIT, UNLICENSE, and COPYING files so the dual-licensing of the original is preserved. The vendored copy lets the oxide scanner ship a slightly customized walker without taking on a registry dependency.

The standalone CLI is built with Bun, not Node

packages/@tailwindcss-standalone/scripts/build.ts runs in Bun to produce a single-binary native CLI. The package's 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 the patches/ directory contains a @parcel/watcher patch and a lightningcss patch — they're targeted at what Bun's static-analysis step can handle.

The browser build watches your DOM

packages/@tailwindcss-browser/src/index.ts doesn't use the Rust scanner at all. Instead it installs a MutationObserver on document.documentElement that re-collects classes from document.querySelectorAll('[class]') whenever an element is added or its class attribute changes. The scanner cost is replaced by a few lines of DOM API. The trade-off: no plugins, no JS config, and @import only works for a hard-coded set of asset URLs.

"Oxide" is named for the engine, not the team

The Rust crate that backs @tailwindcss/oxide is internally named tailwindcss-oxide (crates/oxide/Cargo.toml). The crates/node/ crate, which compiles down to the published npm package, also calls itself "oxide" in user-visible places. The naming reuses the Mozilla Oxidation Project convention of attaching "oxide" to the Rust replacement of a previously non-Rust component.

Bot commits are a non-trivial fraction of history

About 18% of all commits on main are attributed to bots — overwhelmingly dependency-bump commits from depfu[bot], dependabot[bot], and dependabot-preview[bot]. The number is a lower bound for AI- or automation-assisted work because inline AI assistance leaves no metadata in git history.

There are exactly four GitHub Actions workflows

Despite shipping cross-platform binaries, NPM packages, a Rust crate, and a Bun-built standalone, the entire CI/release surface is just .github/workflows/ci.yml, integration-tests.yml, prepare-release.yml, and release.yml. The two release workflows together are over 25,000 bytes.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Fun facts – Tailwind CSS wiki | Factory