@teacss/core
v0.10.11
Published
TeaCSS engine core — token parsing, condition resolution, rule matching, and CSS generation.
Readme
@teacss/core
The framework-neutral TeaCSS parser and generator. Core parses colon-syntax tokens, resolves trailing conditions, matches preset rules, and emits layered CSS. Presets own the utility vocabulary.
bun add @teacss/core @teacss/preset-standardimport { createGenerator } from "@teacss/core";
import { presetStandard } from "@teacss/preset-standard";
const generator = await createGenerator({ presets: [presetStandard()] });
const { css } = await generator.generate("p:4 bg-color:red-500@hover");Applications normally use a build adapter or @teacss/cli. Use Core directly when
authoring presets, generators, or tooling. Core does not discover CSS entries,
manage a build tool, or compose runtime class strings.
Key APIs
| API | Purpose |
| ---------------------- | ----------------------------------------------------------------- |
| createGenerator | Resolve presets and create a CSS generator. |
| splitClassTokens | Split class whitespace while preserving attached [] literals. |
| expandGroups | Expand groups while scanning host source. |
| expandClassGroups | Expand groups in an isolated class list. |
| applyExtractors | Extract tokens into a supplied accumulator or a new Set. |
| compareParentAtRules | Apply the generator's deterministic parent-rule order. |
| comparableWidth | Normalize comparable media-query widths. |
Rule declaration tuples use [property, value, operators?]. Core serializes
the property and value; the optional third slot is available to custom
processors. The default extractor supports quoted and valid unquoted HTML class
attributes, along with JavaScript, TypeScript, JSX, TSX, and MDX source.
Rule and shortcut names
Ordinary rules require declaration-shaped inputs (property:value). Static rule
names, including their configured prefix, are validated when indexes are built;
bare names throw TypeError. Dynamic rules receive only declaration inputs.
Preprocessors, variants, internal metadata, and output aliases do not bypass
this boundary.
Register bare compositions through shortcuts. Shortcut leaves may be other
shortcuts, declarations, or inline CSS objects. A registered prefixed shortcut
can complete its own stripped leaves with its matched prefix; public helper
arguments or edited expansion lists cannot grant that ownership. The parser
itself remains vocabulary-neutral, and arbitrary application class names remain
unmatched without warnings.
Generation
generate() accepts tokens and configured safelist entries. Safelists support
group syntax such as {p:4;m:2}@hover; pass
safelist: false to omit them for a call. For a large direct token set, pass a
positive tokenConcurrency limit. Output order remains deterministic.
await generator.generate(tokens, { tokenConcurrency: 256 });With extendedInfo: true, matched is a Map; otherwise it is a Set. If
the option is a runtime boolean, narrow with matched instanceof Map before
reading extended token information.
With details enabled (the default in dev), copied utilities carry their rule
context. Each payload owns one theme snapshot that its utilities share: one
token's matched data, a parseToken result, or a preflight's
context.generated. Mutating context.theme there never reaches the
generator or another payload, but it is visible to the other utilities in the
same payload.
outputToCssLayers: { allLayers: true } declares configured and emitted layers
in cascade order, including unused configured layers. The experimental scope
option accepts a selector or selector list and scopes generated utility
selectors, but not raw CSS or preflights. Rule metadata noScope bypasses it,
and so does an at-rule head such as @keyframes or @property.
Adapters that extract tokens outside Core can pass a synchronous
isInputCurrent: () => boolean check. If it returns false, generation rejects
so the adapter can re-extract before retrying. Running hooks and diagnostics
already delivered are not rolled back.
Configuration lifecycle
Create initialized instances with await createGenerator(); TeacssGenerator
is a type-only export. prepareConfig(nextConfig) creates an isolated candidate;
commitConfig(prepared) publishes it only while that candidate is current.
Failed preparation leaves the live configuration unchanged.
configResolved(config) hooks run sequentially in preset order, followed by the
user hook. Core awaits each hook and rebuilds rule indexes afterward. A throw or
rejection aborts resolution. Configuration observers are notified separately.
Themes deep-merge while both sides are plain objects. Use { $reset: true } to
replace a branch, or extendTheme for explicit composition. Preset preflights
receive the current call's generated utilities through context.generated.
The compatibility helpers parseVariantGroup() and expandVariantGroup()
accept a MagicStringLike buffer and reject overlapping or unreadable target
ranges before writing group edits.
