Dart Sass and LibSass in one codebase: can @use modules and slash division coexist safely?
0 reputation · 13 Apr 2022, 06:29 UTC
0 reputation · 13 Apr 2022, 06:29 UTC
A shared style library is consumed by two build pipelines: one compiles with Dart Sass (the sass npm package), the other still runs a LibSass-based compiler. Core syntax like variables, nesting, and mixins is expected to match because both implementations historically followed the same sass-spec suite, but the module system and division behavior are known divergence points.
The library currently uses @import everywhere, which Dart Sass flags as deprecated while LibSass never implemented @use at all. Migrating to @use is not purely mechanical: namespacing and load-once semantics can change cascade and variable-override behavior, and LibSass would fail to compile it outright. Slash division is a second concern, since Dart Sass restricts / as division and pushes math.div(), while LibSass keeps the older interpretation.
Assume current Dart Sass as of 2026 and the final LibSass release; exact warning text should be verified against the installed versions.
math.div() compile under LibSass, or must division be avoided entirely in shared files?29775 reputation · 13 Apr 2022, 10:10 UTC
No, @use modules and slash division cannot coexist safely in a shared codebase compiled by both Dart Sass and LibSass. LibSass does not recognize the @use rule and will throw a compilation error upon encountering it. Furthermore, while both compilers handle division, Dart Sass has deprecated the / operator for division in favor of math.div(), whereas LibSass continues to treat / as division. This divergence leads to either build failures or inconsistent CSS output.
The @use and @forward rules are exclusive to Dart Sass. They introduce namespacing and ensure that files are loaded only once. Because LibSass is a legacy implementation that reached its end-of-life without implementing these features, any file utilizing the module system is fundamentally incompatible with a LibSass pipeline.
Historically, Sass used / for division. Dart Sass now treats / as a separator (similar to CSS shorthand) unless it is clearly a mathematical operation. To ensure portability, math.div() is the standard for Dart Sass, but math.div() is a built-in module function that LibSass cannot resolve.
To maintain a single source of truth that compiles identically across both implementations, adhere to these restrictions in shared files:
@import only: Avoid @use and @forward.math.div(): Since LibSass cannot process the sass:math module, you must rely on the legacy / operator.(100% / 3).To determine which compiler your build tool is resolving, check the version output via the CLI:
sass --version
Dart Sass will typically identify as "Dart Sass", while LibSass (often wrapped in node-sass) will report a version number associated with the LibSass C++ core (e.g., 3.6.x). If using a bundler, check the package.json to see if sass (Dart) or node-sass (LibSass) is listed as the dependency.
To refine this recommendation, please provide the exact version of LibSass currently in use. Versions prior to the final 3.6.x release may have additional discrepancies in how they handle the sass-spec, which could further limit the portable subset.
Use comments to ask for clarification. Post a solution as an answer.
3,130 reputation · 13 Apr 2022, 16:17 UTC
One point worth adding to the existing answer: before attributing output differences to language divergence, confirm which compiler each pipeline invokes. Many tools accept both sass and node-sass (LibSass) and silently prefer whichever is installed — webpack's sass-loader, for example, resolves an implementation at runtime unless you set its implementation option explicitly. A monorepo can easily end up with both packages in node_modules via transitive dependencies.
Practical checks: run npx sass --version and npx node-sass --version, inspect the lockfile for both packages, and log the resolved implementation in the loader config. Also note that sass-loader defaults and version behavior change over time, so verify against your installed version rather than assuming.
On division: since math.div() requires @use "sass:math", which LibSass cannot parse, shared files must either avoid numeric division entirely or keep parenthesized / division and accept Dart Sass deprecation warnings during the transition.