TeaCSS has three parts: the teacss build package, a build adapter, and a CSS
entry that selects presets and source files. No preset is selected implicitly.
This guide uses the published 0.7.1 API; the matching
Storybook installation walkthrough
shows the setup interactively.
Install an adapter
Use Node.js 22.12.0 or later for TeaCSS. Install teacss and the adapter
as development dependencies; add the host framework if the application does
not already provide it:
| Host | Bun | npm |
|---|---|---|
| Astro | bun add -d [email protected] @teacss/[email protected] |
npm install -D [email protected] @teacss/[email protected] |
| Vite | bun add -d [email protected] @teacss/[email protected] |
npm install -D [email protected] @teacss/[email protected] |
| Standalone CSS | bun add -d [email protected] @teacss/[email protected] |
npm install -D [email protected] @teacss/[email protected] |
The Astro adapter requires Astro 7 or later and Vite 8 or later.
For runtime class composition, separately install @teacss/[email protected]
as an application dependency. It owns cn, recipe, and their types; the
teacss root does not export them. Other supported adapters include
@teacss/rsbuild, @teacss/postcss, and @teacss/bun; their package READMEs
own the host-specific steps.
Create the CSS entry
Put this at the project-root index.css:
@presets "standard,icons,official";
@source "./src/**/*.{astro,html,js,jsx,ts,tsx}";
@teacss;@presets opts into comma-separated vocabularies. Standard supplies atomic
rules, conditions, theme variables, and preflight; Icons and Official are
independent groups. Start with all three and remove unused groups explicitly.
@source identifies files that contain complete class tokens, including
packages whose markup uses utilities. @teacss inserts the generated CSS.
A missing source path can leave visible classes with no emitted rules.
Standard defaults to on-demand theme variables. If application CSS or inline
styles read those variables directly, keep full preflight with a local preset
module such as teacss-standard.ts:
import { presetStandard } from "teacss/preset-standard";
export default presetStandard({ preflight: true });Select that module in the CSS entry with
@presets "./teacss-standard.ts,icons,official";. It replaces the named
Standard preset while retaining its reset and complete theme variables.
Globs are relative to the CSS entry. If the entry is src/index.css, write
@source "./**/*.{astro,html,js,jsx,ts,tsx}"; instead. Entry discovery checks
package.json#teacss.entry, then index.css, then src/index.css. A
conventional entry must contain a top-level empty @teacss; directive.
The entry also owns registered theme values, shortcuts, and role choices:
@presets "standard";
@source "./src/**/*.{astro,html,js,jsx,ts,tsx}";
@custom {
--color-brand-500: #0f766e;
}
@teacss;This makes bg-color:brand-500 available. For reusable component colors,
prefer the seven semantic roles in Palette.
Mode and role selections belong on <html>; there are no nested named themes.
There is no teacss.config.* file or @theme directive. For a nonstandard
entry location, declare the file explicitly:
{
"teacss": {
"entry": "./src/styles/tea.css"
}
}Connect Astro
The Astro integration registers the Vite plugin and injects the generated stylesheet into pages:
// astro.config.mjs
import { defineConfig } from "astro/config";
import { teacss } from "@teacss/astro";
export default defineConfig({
integrations: [teacss()],
});Do not import virtual:teacss.css again with Astro’s default injection.
To own the import instead, pass teacss({ injectEntry: false }) and import
the virtual stylesheet once. injectExtra appends module statements without
replacing the default stylesheet import.
When using Astra and Aster
Their components rely on the application’s TeaCSS build. Import Astra’s shortcut declarations and scan both packages, including their CSS and Astro files, from the project-root entry:
@import "@teasim/astra/index.shortcuts.css";
@presets "standard,icons,official";
@source "./src/**/*.{astro,html,js,jsx,ts,tsx,md,mdx,css}";
@source "./node_modules/@teasim/astra/dist/**/*.{js,astro,css}";
@source "./node_modules/@teasim/aster/dist/**/*.{js,astro,css}";
@teacss;Keep both packages in Astro’s SSR build with
vite: { resolve: { noExternal: ["@teasim/astra", "@teasim/aster"] } }.
An application using only Astra can omit the Aster path and SSR entry.
Teasim 0.5.0 has its own Node.js and Astro requirements; see
Astra and Aster.
Connect Vite
For a non-Astro Vite application, register the plugin and import its virtual stylesheet once from the application entry:
// vite.config.ts
import { defineConfig } from "vite";
import { pluginTeacss } from "@teacss/vite";
export default defineConfig({
plugins: [pluginTeacss()],
});// src/main.ts
import "virtual:teacss.css";The adapter scans the module graph, updates CSS during development, and emits a CSS asset for production.
Generate a standalone stylesheet
When no bundler owns the module graph, the CLI reads the same CSS entry:
bunx teacss "src/**/*.{ts,tsx,html}" -o tea.css --unmatched error
bunx teacss --check--check prints the resolved configuration without writing CSS; it is not a
rendered-page or all-token validation. Without a CSS entry, pass
--preset standard explicitly. The CLI flag is singular; the CSS directive
is @presets. Run bunx teacss --help for watch mode and other options.
Confirm the output
Put a literal token in a scanned file, such as
<div class="p:4 bg-color:neutral-100">Hello</div>, then build and inspect the
corresponding padding and background rules. An unknown or near-known value
can fail with unmatched: "error" or CLI --unmatched error, but unrelated
class names are ignored. Check the final HTML and CSS as well.
If a class has no rule, inspect the source glob, enabled preset, token spelling,
and entry import. TeaCSS cannot discover "p:" + size; keep complete tokens
static or declare their exact possibilities with @safelist.