Migrating Less 4.x → 5.x
Coming to Jess from Less 4.x? Jess is the engine behind Less 5.x, so the same breaking changes apply when you move existing Less sources onto Jess. This page lists the ones that most often need attention.
Removed: inline backtick JavaScript
Inline backtick JavaScript is removed entirely. It is now a parse error — not a flag you can opt back into.
// No longer valid — this is a parse error:
@columns: `Math.max(12, 8)`;
In Jess there is no inline-JavaScript syntax at all. Move any scripted values to
a module you pull in with @-use, or express them with built-in functions
(@columns: max(12, 8);).
Imports
Jess's module system is @-compose (namespaced import, isolated scope,
with { } configuration). In .jess a bare @import is always a plain CSS
at-rule (passed through — no extension heuristic); it is never a source include.
To fold a stylesheet in and evaluate it, use an explicit dash-prefixed rule:
@-compose (preferred) or @-import (mechanical port; warns). The compiler
at-rules require the dash — bare @use/@compose are not valid Jess.
// CSS @import (passed through), NOT a source include:
@import "foo";
// Legacy source include (warns) — prefer @-compose:
@-import "./foo.less";
// The module system:
@-compose "./foo.less" as foo;
See Modules & imports.
CSS nesting is preserved by default (collapseNesting: false)
Less 5.x has first-class CSS nesting, and it keeps nested structure by default
(collapseNesting: false). Output stays in the familiar nested shape unless you
explicitly opt into collapsing.
.card {
padding: 1rem;
.title { font-weight: 600; }
}
By default this compiles to nested CSS (.title stays nested under .card).
Enable collapseNesting: true for the older flattened (.card .title { … })
output when you need deduplication or wider tooling support.
If you are porting a 4.x project that assumed flattened output, set
collapseNesting: true while you migrate, then move to native nesting once your
toolchain supports it.
Less-style parent-suffix composition still works, and the parent-template model is now explicit:
&-1composes a suffix onto the parent (.col { &-1 {…} }→.col-1).&()keeps the parent selector but hoists the nested selector to root.&('')drops the parent selector entirely.&(-1)is equivalent to&-1.
extend and the !all flag
extend behavior is validated against fixture parity, including nested and
media-scoped selectors. Per-selector all in multi-target extends is deprecated
in favor of a single !all flag:
// Deprecated:
&:extend(.a all, .b all);
// Preferred:
&:extend(.a, .b !all);
With collapseNesting: true, extend … !all in nested selector-list cases may
emit :is(…) selectors to reduce duplication.
Variable resolution follows source order
Less 4.x had eager-resolution edge cases where a later mixin call could appear to retroactively change an earlier declaration. Less 5.x resolves declarations in source order against the scope that exists when they are evaluated — a later side effect does not rewrite an already-evaluated sibling declaration.
@mix: blue;
.mixin() { @mix: #989; }
.tiny-scope {
color: @mix; // blue — resolved before .mixin() runs
.mixin();
}
Math modes
- Move
strictMathworkflows to themathoption. strict-legacymath mode is removed.math=alwaysis deprecated; treat it as legacy behavior.
# old
lessc --math=always styles.less styles.css
# preferred
lessc --math=parens-division styles.less styles.css
Deprecated CLI / option paths
--relative-urls→--rewrite-urls=all(orrewriteUrls).--ie-compatis a no-op in modern pipelines.- built-in
compress→ use a dedicated CSS minifier. dumpLineNumbers/--line-numbers→ use sourcemaps.strictImportsis deprecated; avoid it in new configs.
Runs on the Jess engine
Jess is the engine. Less 5.x is Jess with the Less-compatibility surface turned on, so the evaluation model described throughout these docs is exactly what your migrated Less sources run against.