Skip to content
TeaCSS documentation

Installation

Install TeaCSS, declare its CSS entry, and connect Astro, Vite, or the standalone CLI.

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:

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:

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:

css
@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:

json
{
  "teacss": {
    "entry": "./src/styles/tea.css"
  }
}

Connect Astro

The Astro integration registers the Vite plugin and injects the generated stylesheet into pages:

ts
// 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:

css
@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:

ts
// vite.config.ts
import { defineConfig } from "vite";
import { pluginTeacss } from "@teacss/vite";

export default defineConfig({
  plugins: [pluginTeacss()],
});
ts
// 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:

sh
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.

Continue with Syntax and Standard.