Coming from Sass
If you know Sass/SCSS, you already know most of Jess. Jess parses SCSS today, maps its constructs onto a real AST, and — where Sass made a compromise it later regretted — offers a cleaner equivalent. The supported subset has a name: Sass+, "Sass without the bad parts."
This guide is the path a Sass user takes through the docs: understand what maps, what is intentionally left out, where Jess is stricter, and then how to move a codebase over.
Start here
- Sass+ support matrix — the canonical, verified statement of what works today, what is excluded by design, and what is still coming. Read this first if you are sizing up a migration.
- Sass (SCSS) compatibility —
how SCSS syntax maps into Jess:
@use→@-compose,#{…}interpolation, maps → collections,map.get()→ reference lookups, placeholders,!global/!default. - Unsupported Sass+ features —
the Sass constructs Jess parses but will not evaluate (
@at-root,@forwardshow/hide/as), and the Jess-native way to get the same result. - Stricter than Sass — invalid CSS that Sass tolerates (bogus combinators, escaped directive keywords) and that Jess rejects at parse time. Valid CSS is the reference.
When you are ready to port a project to native .jess, see
Migrating to Jess for the full Sass → Jess
mapping tables. Migration is manual today — there is no automated converter.
The one-line mental model
| Sass | Jess | Notes |
|---|---|---|
$color: #06c; | $color: #06c; | Same declaration spelling. Native Jess also permits $$color:; either declaration creates/updates both bindings. Reads use $color for live/current or $$color for scoped/final lookup. |
#{$x} | ${…} in identifier/string position; $(…) / $[…] in value position | One form per position — interpolation vs expression vs lookup. |
@mixin / @include | box() {} / $ > box(); | See Migrating to Jess. |
@use "./x" | @-compose "./x" | Namespaced module import, isolated scope. |
@forward "./x" | @-export "./x" | Forwarding (no show/hide filtering). |
@extend .a / %p | $extend .a; | Selector reuse. |
Jess keeps compiler-level at-rules dash-prefixed (@-compose, @-use,
@-export) so they never collide with the evolving CSS standard library. That is
why you see @-compose and not a bare @compose.