@axiom-core/runtime-engine
v0.1.1
Published
Axiom Core — runtime theme engine
Downloads
268
Readme
@axiom-core/runtime-engine
The canonical Axiom runtime. Composes primitive tokens with semantic token definitions, applies axis transforms, resolves all token references, and produces a deterministic resolved theme object.
runtime-engine does NOT emit CSS and does NOT integrate with any UI framework. It is a pure data-transformation pipeline. Framework integration is handled by @axiom-core/react-adapter and @axiom-core/vue-adapter, which consume the resolved theme output from this package.
Installation
pnpm add @axiom-core/runtime-engineArchitecture
The resolution pipeline is a strict, ordered sequence of pure transforms:
primitives (PrimitiveTokens — raw values: colors, spacing, typography…)
↓
semantic tokens (SemanticTokens — references into primitives, structured by namespace)
↓
axis registry (Record of ThemeAxis → transform functions)
↓
composeTheme() (applies active axis transforms to the semantic token tree)
↓
resolveReferences() (replaces every TokenReference { ref } with its primitive value)
↓
resolved theme (ResolvedSemanticTokens — plain values, no references, ready to emit)Each step is a pure function. No global state, no counters, no timestamps. Identical inputs always produce identical outputs.
API
createThemeManager(options)
Creates and returns a theme manager bound to the provided token configuration.
import { createThemeManager } from '@axiom-core/runtime-engine';
import { enterprisePrimitives } from '@axiom-core/primitives';
import { baseSemantic, semanticAxes } from '@axiom-core/semantic-baseline';
const manager = createThemeManager({
primitives: enterprisePrimitives,
baseSemantic,
registry: semanticAxes,
initialConfig: { mode: 'light' },
});Options
| Option | Type | Description |
|---|---|---|
| primitives | PrimitiveTokens | The primitive token set — raw values for colors, spacing, typography, shadows, etc. |
| baseSemantic | SemanticTokens | The semantic token tree. Leaves are TokenReference objects pointing into primitives. |
| registry | AxisRegistry | Map of axis names to pure transform functions ((semantic, config) => SemanticTokens). |
| initialConfig | ThemeConfig | Initial axis configuration, e.g., { mode: 'light', brand: 'default' }. |
Returned Manager Methods
| Method | Signature | Description |
|---|---|---|
| getTheme() | () => ResolvedSemanticTokens | Returns the current fully resolved theme. All TokenReference leaves have been replaced with their primitive values. |
| getConfig() | () => ThemeConfig | Returns the current active axis configuration. |
| setConfig() | (config: ThemeConfig) => void | Replaces the full axis config and recomputes the resolved theme. |
| updateAxis() | (axis: ThemeAxis, value: string) => void | Updates a single axis and recomputes the resolved theme. |
| subscribe() | (listener: () => void) => () => void | Registers a listener called whenever the resolved theme changes. Returns an unsubscribe function. |
Usage Example
import { createThemeManager } from '@axiom-core/runtime-engine';
import { enterprisePrimitives } from '@axiom-core/primitives';
import { baseSemantic, semanticAxes } from '@axiom-core/semantic-baseline';
// Create the manager
const manager = createThemeManager({
primitives: enterprisePrimitives,
baseSemantic,
registry: semanticAxes,
initialConfig: { mode: 'light' },
});
// Read the current resolved theme
const theme = manager.getTheme();
console.log(theme.surface.background); // e.g. "#ffffff"
// Subscribe to theme changes
const unsubscribe = manager.subscribe(() => {
console.log('Theme changed:', manager.getTheme());
});
// Switch to dark mode
manager.updateAxis('mode', 'dark');
// Clean up
unsubscribe();
// Replace entire config at once
manager.setConfig({ mode: 'dark', brand: 'enterprise', density: 'compact' });Axis Model
Axes are named dimensions of variation applied to the semantic token tree before reference resolution. Each axis handler is a pure transform — it receives the current semantic token tree and the active config and returns a new semantic token tree.
Built-in Axes
| Axis | Values | Description |
|---|---|---|
| mode | 'light' \| 'dark' | Light/dark color scheme. Controls surface, content, and border token mappings. |
| brand | 'default' \| 'enterprise' \| … | Brand variant. Overrides primary color and brand-specific token refs. |
| density | 'comfortable' \| 'compact' \| 'spacious' | Spacing and size density. Scales spacing and typography tokens. |
| contrast | 'standard' \| 'high' | Accessibility contrast level. Remaps content and border tokens for WCAG compliance. |
| material | 'flat' \| 'elevated' \| 'transparent' | Surface material treatment. Controls elevation and overlay token mappings. |
Axis handlers are registered in the registry option and are called in a deterministic order (alphabetically by axis name) to ensure axis application is order-independent.
Determinism Guarantee
runtime-engine is designed to produce identical output for identical inputs, regardless of environment, call order, or timing.
This is enforced by:
- Pure axis transforms — no closures over mutable state
- Reference resolution order — sorted by token path, not insertion order
- No timestamps, counters, or RNG — zero sources of non-determinism
- Golden hash CI enforcement —
scripts/validate-golden-hash.jsrejects any drift in the reconstructed CSS variable output
If getTheme() is called with the same primitives, baseSemantic, registry, and config, it will return a structurally identical resolved theme on every call, in every environment.
TypeScript
import type {
ThemeManager,
ThemeConfig,
ThemeAxis,
ResolvedSemanticTokens,
} from '@axiom-core/runtime-engine';Relationship to Other Packages
@axiom-core/runtime-engine ← YOU ARE HERE
↙ ↘
@axiom-core/react-adapter @axiom-core/vue-adapterruntime-engine has no framework dependencies. React and Vue adapters accept the manager (or its resolved theme output) and handle CSS variable emission, DOM injection, and reactivity.
License
MIT
