Theme Engine: ref() token references not resolved in ejected CSS
Bug Description
The ref() helper function in @theme-engine/helpers/define-theme creates token references (e.g., $global.primaryColor) that are not properly resolved when generating static CSS via the eject CLI.
Expected Behavior
When using ref() to reference another token:
tokens: {
'global.primaryColor': '#D49653',
'tooltip.bg': ref('global.primaryColor'), // Creates '$global.primaryColor'
}
The ejected CSS should output either:
- Resolved value:
--tooltip-bg: #D49653; - CSS var reference:
--tooltip-bg: var(--global-primaryColor);
Actual Behavior
The ejected CSS outputs the raw reference string, which is invalid CSS:
--tooltip-bg: $global.primaryColor;
Root Cause
The BaseResolver.handleCheckExplicit() method in engine/core/base-resolver.ts:210-226 returns explicit values as-is without checking if they are $tokenPath references that need further resolution:
protected handleCheckExplicit(ctx: ResolutionContext<TValue>, frame: ResolutionFrame): void {
const explicitValue = ctx.values[frame.path];
if (explicitValue !== null && explicitValue !== undefined) {
// Returns value as-is, even if it's a '$...' reference
ctx.results.set(frame.path, explicitValue);
ctx.stack.pop();
return;
}
// ...
}
The CSS generator in engine/eject/generate-css.ts:72 also outputs values without transformation:
lines.push(`${indent}${cssVarName}: ${value};${newline}`);
Steps to Reproduce
- Create a theme using
ref():
import { defineTheme, ref } from '../engine/helpers/define-theme';
export default defineTheme({
$meta: { id: 'test', name: 'Test', version: '1.0.0' },
tokens: {
'global.primaryColor': '#D49653',
'tooltip.bg': ref('global.primaryColor'),
},
behaviors: {},
});
- Run the eject CLI:
npx tsx packages/theme-engine/cli/eject.ts -t path/to/theme.ts -o /tmp/test
- Check the output CSS - it contains
$global.primaryColorinstead of a valid value.
Affected Files
packages/theme-engine/engine/core/base-resolver.ts- Resolver doesn't expand$referencespackages/theme-engine/engine/eject/generate-css.ts- CSS generator doesn't transform$tovar()packages/theme-engine/engine/helpers/define-theme.ts- Documentsref()but feature is incomplete
Suggested Fix Options
Option A: Resolve at build time
Modify the resolver to detect $tokenPath values and resolve them to concrete values by looking up the referenced token.
Option B: Convert to CSS var()
Modify the CSS generator to transform $token.path → var(--token-path) for runtime resolution.
Option C: Hybrid approach
- For eject (static CSS): Resolve to concrete values
- For runtime: Convert to CSS var() references
Workaround
Until fixed, avoid using ref() and instead:
- Rely on fallback chains (which work correctly)
- Use hardcoded values for tokens without applicable fallbacks
Environment
- Package:
@theme-engine - File:
packages/theme-engine/themes/stunning.theme.ts
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗