birch-css-utils

Semantic color themes for Tailwind CSS 4. Keep every utility you already
use, and add coordinated palettes with light, dark, and system modes, plus
optional scoped base styling. This initial release derives from
Tailwind CSS 4.3.3 and retains its unmodified compiler and public entry
points (see NOTICE.md and UPSTREAM.json).
Highlights
- Six coordinated palettes:
ocean (default), forest, ember, gruvbox,
dracula, and catppuccin.
- One attribute switches light, dark, or system mode; no utility rewrites.
- Semantic tokens (
bg-primary, text-muted, border-danger, ...) that
work with ordinary Tailwind modifiers and opacity.
- Text/background pairings checked for a 4.5:1 contrast ratio.
- Optional base styling for buttons, fields, and headings, scoped behind an
opt-in attribute.
- Zero runtime JavaScript; plain CSS custom properties, generated at build
time and shipped ready to use.
Requirements
- Tailwind CSS 4.3.3 and its matching
@tailwindcss/postcss adapter.
Other versions and Vite/CLI integrations are not yet verified.
- Node.js >= 20 to build or develop the kit; consumers need no build step.
Install
Alongside upstream (reversible)
Keep Tailwind as-is and layer the themes on top:
npm install -D birch-css-utils
@import "tailwindcss";
@import "birch-css-utils/themes.css";
Only the --twt-* custom properties are added by the second import; remove it
to return to stock Tailwind.
Drop-in replacement
Install the kit under the tailwindcss dependency name to keep existing
imports, JavaScript plugin imports, and PostCSS configuration untouched:
npm install -D tailwindcss@npm:birch-css-utils
@import "tailwindcss";
Keep @tailwindcss/postcss at version 4.3.3. Its compiler dependency may
install a separate upstream copy; your app's CSS import still resolves to this
package.
Usage
Choose a palette and mode on the document root:
<html data-theme="forest" data-mode="dark">
The default palette is ocean. data-mode="light" and data-mode="dark"
are explicit overrides; omit data-mode to follow the operating system. A
nested theme island should specify both data-theme and data-mode
explicitly.
<section class="rounded-xl border border-border bg-surface p-6 text-foreground">
<p class="text-muted">Your theme changes; these classes stay the same.</p>
<button class="rounded-lg bg-primary px-4 py-2 text-primary-foreground hover:bg-primary-hover">
Save changes
</button>
</section>
Available color tokens:
| Surfaces | background, surface, surface-raised |
| Text and borders | foreground, muted, border, ring |
| Main action | primary, primary-hover, primary-foreground |
| Secondary action | secondary, secondary-foreground |
| Feedback | success, warning, danger, each with a -foreground companion |
Tokens work with ordinary Tailwind modifiers, including hover:bg-primary,
md:text-muted, and bg-primary/50. App-level @theme declarations can
override semantic colors. The common misspelling catpuccin is accepted as
an alias for the Catppuccin palette.
Theming and Tailwind's dark: variant are separate. data-mode switches
semantic values. The existing dark: variant keeps its upstream media-query
behavior, preserving compatibility.
Optional base styling
@import "birch-css-utils/base.css";
<body data-twt-ui>
<button>Uses the theme's action styles</button>
</body>
This opts into heading, button, field, focus, and page defaults. The styles
live in the base layer, so utility classes can override them. Remove this
import before switching back to upstream, which does not export base.css.
Compatibility contract
- Existing utility names, palettes, spacing, typography, breakpoints, and
Preflight retain their upstream behavior. Default imports add custom
properties only.
- Themes add
bg-primary, text-muted, border-danger, and related
utilities. They do not redefine classes such as bg-teal-600 or
rounded-xl.
- Base element styling requires both a separate CSS import and
data-twt-ui.
- CSS generation is verified against upstream Tailwind 4.3.3: standard
variants, palettes, arbitrary values, and utilities generate identical CSS,
excluding the new
--twt-* custom properties.
Local development
npm ci
npm test
npm run check:upstream
npm run demo:build
Open examples/playground/index.html after building the demo to switch
between all six palettes in light, dark, or system mode.
npm run demo:check verifies computed theme colors and controls in a headless
browser, including system dark mode (set CHROME_PATH for a non-default
Chrome/Chromium installation).
src/themes.mjs is the source of truth for palettes; npm run build
regenerates themes.css. Generated CSS is included in the npm package, so
consumers need no theme-generation step.
Provenance
The compiler is vendored from the verified upstream npm distribution so the
package is self-contained. See NOTICE.md for third-party
notices and UPSTREAM.json for provenance and upgrade
instructions. This is a theme kit release, not a separate compiler
implementation, and is not affiliated with Tailwind Labs.
License
MIT. Original Tailwind Labs notices are preserved, with attribution for the
additional theme work.