Skip to main content

JS-in-CSS

This page describes a planned feature

Compile-time JS/TS evaluation is not implemented in the 2.x alpha. The @-use and @-from at-rules parse and are preserved in the document, but no module resolver exists yet: nothing is loaded, nothing is evaluated, and the at-rule is serialized back out verbatim. Referencing an imported name is currently a compile error (Name not found).

The syntax below is settled and parses today. The behavior is the target.

The plan: Jess evaluates JS/TS at compile time using @-use for Sass-module-style namespace imports or @-from for ESM-style imports, so token data and feature flags can stay in one place while CSS output stays deterministic.

For example:

@-use './tokens.ts';

.box {
width: $tokens.boxWidth;
}

This is intended to produce:

.box {
width: 2px;
}

A namespace can be renamed with as:

@-use './tokens.ts' as t;

.box {
width: $t.boxWidth;
}

@-from is the ESM-style spelling, including named imports and a namespace import:

@-from './tokens.ts' import (boxWidth);

.box {
width: $boxWidth;
}
@-from './tokens.ts' import * as t;

.box {
width: $t.boxWidth;
}

The intent is to keep runtime metadata in JS while still compiling deterministic CSS output.

Also not yet implemented

Beyond resolution itself, two shapes on the roadmap do not parse today:

  • Module members in a condition header. $if ($flags.enableShadow) { … } is rejected by the parser; member access is currently value-position only.
  • A JS function returning a style object (for example { display: 'flex' }) used as a mixin. There is no 2.x splat form for applying a JS object as a rule body.

See Modules & imports for the module at-rule reference.