Migrating Sass from @import to @use and @forward
Replace deprecated Sass @import with Dart Sass modules using @use and @forward, plus explicit namespaces and CI validation.
24 Jan 2026, 23:52 UTC

The decision: stop using @import in Dart Sass
Dart Sass, the reference implementation for Sass, emits deprecation warnings for @import. The rule still compiles, but it loads stylesheets into a single global scope, can duplicate CSS when the same file is imported more than once, and makes it hard to tell which file provided a variable or mixin.
If your project uses Dart Sass, the useful takeaway is to replace @import with the module system: @use for loading dependencies and @forward for re-exporting them. If you still use LibSass, for example the deprecated node-sass package, you must switch to Dart Sass first; LibSass does not support @use or @forward.
Constraints and assumptions
- This guide assumes Dart Sass, distributed as the
sasspackage, not LibSass. @useis not a drop-in replacement for@import. Variables and mixins must be addressed through a namespace unless you explicitly opt into global access.- Circular dependencies between modules cause compilation errors. Organize stylesheets as a directed acyclic graph: a module should not use a file that uses it back.
- Use
@use "path" as *only when global access is intentional. Explicit namespaces are safer in large codebases.
Supported options compared
| Approach | Scope | Loading behavior | Best for |
|---|---|---|---|
@import | Global | Re-parsed on every import; can duplicate output | Legacy stylesheets during migration |
@use | Namespaced by filename | Loaded once per compilation | Component styles, variables, mixins |
@forward | Re-exports selected members | Loaded once; hides internal file structure | Design-system entry points |
@use ... as * | Global | Loaded once | Intentional global themes only |
Trade-offs
Explicit namespaces prevent collisions between identically named variables, but they add verbosity: variables.$primary is longer than $primary. Sass treats members beginning with an underscore as private, so a module can hide helpers it does not want to expose. @forward lets a single entry file re-export variables and mixins without revealing every internal stylesheet to consumers. The main risk is mechanical: every global reference in existing code must be updated to use a namespace.
Implementation example
Consider a small component library with this layout:
src/
_variables.scss
_buttons.scss
index.scss
main.scss
The old main.scss might look like this:
@import "variables";
@import "buttons";
.hero {
color: $primary;
}
Here is the module version. First, _variables.scss:
$primary: #0066cc;
$_internal-helper: "do not export";
Next, _buttons.scss loads variables through a namespace:
@use "variables";
@mixin button($background: variables.$primary) {
background-color: $background;
border: none;
}
Then main.scss uses both modules explicitly:
@use "variables";
@use "buttons";
.hero {
color: variables.$primary;
}
.submit {
@include buttons.button();
}
Finally, index.scss acts as a design-system entry point. It re-exports members without forcing consumers to import each file:
@forward "variables";
@forward "buttons";
A consumer can now write @use "path/to/index" and access index.$primary or index.button(), while $_internal-helper remains private.
Compile and validate
Run these commands in the project root with normal user permissions. Install Dart Sass if it is not already present:
npm install --save-dev sass
Compile the entry stylesheet:
npx sass --no-source-map src/main.scss dist/main.css
Expected checks:
- The command exits with code 0.
dist/main.cssis generated.- Standard error contains no
Deprecation warningmessage for@import. - The compiled CSS contains the expected value from the module, such as
color: #0066cc;forvariables.$primary. Inspectdist/main.cssdirectly or grep for the value.
For CI, add a step that compiles the entry file and fails the build if standard error includes Deprecation warning or if the compiler exits non-zero. This catches any remaining @import usage before it reaches production.
Limitations and rollback
@useis not automatic; existing global references must be rewritten manually.- LibSass cannot compile
@useor@forward. - Circular module dependencies produce errors, so check the import graph if compilation fails unexpectedly.
- Because migration changes source files, rollback means reverting those files to the
@importversion in version control and redeploying the previous compiled CSS.
Verification checklist
- Confirm the project uses Dart Sass, not LibSass.
- Replace each
@importwith@useor@forwardas appropriate. - Add namespaces to all variable, mixin, and function references.
- Compile with Dart Sass and check for
@importdeprecation warnings. - Open the compiled CSS and confirm expected values appear.
- Add the compile check to CI.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.