@cssxio/compiler
v0.9.0
Published
Standalone utility compiler for CSSX.
Readme
@cssxio/compiler
@cssxio/compiler builds static utility strings without a source transform or build tool adapter.
import { compileStyleMap, serializeCss } from '@cssxio/compiler';
const result = await compileStyleMap({
card: 'p-5 bg-white hover:bg-gray-50',
});
const className = result.classNames.card;
const css = serializeCss(result.rules, { layer: 'cssx' });Class names
The style-map compiler APIs accept className. By default CSSX uses compact,
collision-free serial names: s0x, s1x, and so on.
Static style maps also default to reusabilityBudget: 'auto'. CSSX shares
positive-value groups of utilities between repeated styles and leaves each
style with a residual class when needed. Set 0 to keep one complete class per
style or 100 to emit only winning atomic classes.
const result = await compileStyleMap(styles, { reusabilityBudget: 0 });const result = await compileStyleMap(
{ card: 'p-5 bg-white' },
{
className: {
variant: 'serial',
prefix: 'app-',
suffix: '-v1',
},
},
);
// Atomic and composite names: app-0-v1, app-1-v1, …, app-z-v1, app-A-v1, …, app-10-v1serial is a collision-free, case-sensitive base-62 counter for the complete
compilation: 0 through 9, then a through z, then A through Z, then
10. Its default prefix and suffix are s and x (s0x, s1x, …). When
both affixes are explicitly blank, CSSX uses decimal serial names and escapes
digit-leading selectors. The prefix gives it a project namespace. Choose the stable content-hash random variant when that better
fits your build; set
length to fix the hash fragment length when you need a smaller output:
{ className: { variant: 'random', prefix: 'app_', suffix: '_v1', length: 5 } }
// app_0p4jd_v1CSSX resolves collisions deterministically for random names. A fixed random
length must have enough base-36 combinations for every generated atomic and
composite class; otherwise compilation fails instead of reusing a class name.
length applies only to random, and a non-empty prefix must be a safe CSS
identifier prefix. Prefixes and suffixes work with both variants.
When you compile independent maps that share one stylesheet, create one
allocator and pass it as classNameAllocator to every call, including
composeCompiledStyles. This keeps serial values unique across those calls.
const classNameAllocator = createClassNameAllocator();
const first = compileStyleRecords({ button: 'p-4' }, { classNameAllocator });
const second = compileStyleRecords({ card: 'bg-white' }, { classNameAllocator });API
High-level compilation
compileStyleMap(input, options?)asynchronously compiles one object of style names to static utility strings. It returnsCompileResult, containing compiled runtimestyles, one composite class inclassNamesfor each style key, internal candidate metadata, and zero or oneCssxRulewith the generated CSS.options.themeis optional CSSX@themeinput.compileStyleMaps(inputs, options?)asynchronously compiles named style maps together. It returnsCompileMapsResult, with astyleMapsresult for each input and shared CSSrules. Shared keyframes and property registrations are emitted once.serializeCss(rules, options?)removes duplicate rule CSS, sorts it for stable output, and joins it into one string. Setoptions.layerto wrap non-empty output in@layer <layer>{...}.
Lower-level compilation
compileUtilities(candidates, className, themeCss?)asynchronously emits CSS for unique utility candidates.classNameis called once per distinct candidate and must return one or more safe, space-separated CSS class names. The result isUtilityCompilation:cssincludes everything,prefixCsscontains theme and shared resources,entrieslists emitted utility CSS in output order, andclassesmaps candidates to the callback result.describeUtilityRecipe(candidateSource, theme)returnsUtilityRecipefor one already-resolvedCssxTheme. It includes declarationatoms, required keyframes and property registrations inresources, and atom-level semanticwrites.compileStyleRecords(input, options?)returnsCompiledStyleRecordMapfor one static style map. Itsstylesare runtime records,classesmaps candidates to generated classes, andcandidatespreserves each style's parsed utility list.compileStyleRecordMaps(inputs, options?)returnsCompiledStyleRecordMapsfor several maps. It uses one class-name namespace and exposes the sharedclassesmap.classifyUtility(candidate)returns aUtilityConflictRecordwith the candidate's variantscope, writegroup, and clearedconflicts, ornullwhen it cannot be composed safely.mergeCompiledStyles(styles)appliesCompiledStylerecords from left to right and returns the final class string. Later utilities clear conflicting earlier groups in the same scope.
Types
CompilerOptionsconfigures high-level compilation. Its optionalthemeis CSSX@themeinput,classNamecontrols generated class naming, andreusabilityBudgetcontrols static class sharing.StyleCompilerOptionsconfigures compiled record generation with the same optionaltheme,className, andreusabilityBudgetinputs.ClassNameOptionsdefaults toserialnames with ansprefix andxsuffix. It can selectrandom(stable hash), set a sharedprefixorsuffix, and set the random hashlength.ClassNameAllocatormaintains one collision-free naming namespace across independent compiler calls. Create one withcreateClassNameAllocator(options?).CssxRulecontains a stable generatedclassNameand its fullcss.CompileResultcontains one map'sstyles, compositeclassNames,rules, generated atomclasses, and parsedcandidates.CompileMapsResultcontains compiledstyleMapsand sharedrules.CompiledStyleis an opaque ABI-v2 runtime style record marked by$$css;cstores its composite class and_stores orderedCompiledUtilityfallback records.CompiledUtilityis the compact tuple used byCompiledStyle: class name or clear marker, scope, group, then conflict groups.CompiledStyleRecordMapcontains one map'sstyles, candidateclasses, and parsedcandidates.CompiledStyleRecordMapscontains namedstyleMapsand their sharedclasses.UtilityConflictRecorddescribes a composable utility'sscope, primarygroup, andconflicts.UtilityDeclarationis one emitted CSS declaration. It can include selector, at-rule, and semantic metadata for atomization and composition.UtilityCompilationis the result ofcompileUtilities, with completecss, sharedprefixCss, orderedentries, and candidateclasses.UtilityCssEntrycontains one sourcecandidateand thecssemitted for it.UtilityRecipedescribes one candidate's declarationatoms, sharedresources, and semanticwrites.UtilityRecipeResourceslists requiredkeyframesand registered customproperties.UtilityWriteSetnames one atom's semanticgroupandconflicts.CssxThemeis resolved theme data:tokens,keyframes, outputmode, and variableprefix.ThemeOutputModeisinline,reference, orstatic. Inline output writes resolved values in rules; reference output emits used variables; static output emits all theme variables.
theme is CSSX @theme input added to the default theme. CSSX validates it, resolves token references while building, and rejects invalid declarations, unsafe values, missing tokens, and circular references. Custom color and breakpoint tokens can define utility values without adding global CSS.
Tailwind 4.3.3 conformance
The compiler includes checked-in semantics for every static candidate in the
pinned Tailwind CSS 4.3.3 IntelliSense snapshot. Tailwind is used only to
regenerate that reviewed data during development; it is not a runtime, build,
or published dependency. CSSX also accepts its @theme tokens and safe
arbitrary property/value/selector forms. Tailwind plugins, legacy JavaScript
configuration, and Tailwind @utility or @variant extensions are excluded.
Motion compilation
CSSX emits motion as native CSS declarations and at-rules. Transition and animation longhands compose independently with shorthands; a later shorthand resets its components, while a later longhand preserves the earlier shorthand and overrides only that component. Referenced keyframes come from compiled recipe declarations and are emitted once.
motion-safe: and motion-reduce: emit reduced-motion media queries.
starting: emits @starting-style. Scroll/view timeline, animation range, and
View Transition utilities are wrapped in property-specific feature queries.
vt-old-[target]:, vt-new-[target]:, vt-group-[target]:, and
vt-image-pair-[target]: emit terminal pseudo-element selectors intended for a
class on the document element.
The compiler does not add a motion runtime. It does not observe elements,
delay removal, interpret gestures, run spring simulations, project layout, or
initiate View Transition transactions. Spring utilities resolve to static
linear() easing tokens.
CSSX keeps property atoms internally when dynamic composition may need to
replace one channel, such as px-4 followed by pr-2. Static style keys and
locally resolvable compositions still expose one composite class.
Historical compatibility references are documented in THIRD_PARTY_NOTICES.md.
Compiler build integrity
Each compiler build writes dist/BUILD_MANIFEST.json. It stores a SHA-256
hash for the source files and each published file. The package check compares
the manifest with the generated files before publishing.
