Choosing @use Over @import in Dart Sass: A Practical Decision Guide
When refactoring a growing Sass codebase, choosing between legacy @import and modern @use matters. This guide explains the trade‑offs, compares options in a compact table, and walks through a practical migration example that keeps build times under 2 seconds.
14 Jan 2026, 13:05 UTC

Problem & Takeaway
When refactoring a growing Sass codebase, you must decide whether to keep legacy @import or switch to the modern @use/@forward module system. The key takeaway: use @use with explicit namespaces to avoid global scope pollution, keep CSS output lean, and future‑proof your styles.
Decision & Constraints
Decision: adopt @use (with namespace) for new modules while gradually migrating existing @import files.
- Must run on Dart Sass 1.60+ (the only implementation that fully supports
@use). - Project already contains ~200 SCSS files with heavy
@importusage. - Build pipeline must stay under 2 seconds for a medium‑sized project.
- Existing UI must not regress during migration.
Options Compared
| Feature | @import | @use | @forward |
|---|---|---|---|
| Namespace control | None – all names go to global scope | Explicit alias or * wildcard; encapsulation possible | Re‑exports selected members; still requires @use to import |
| Private members | Impossible – everything is global | Members prefixed with _ are private to the module | Same as @use – private members stay hidden |
| CSS output size | Can duplicate code if modules are imported multiple times | Each module is imported once; no duplication | Same as @use – reduces duplication when re‑exporting |
| Build speed | Higher parsing overhead due to repeated imports | Lower – modules are cached after first import | Similar to @use – negligible extra cost |
| Migration effort | Zero – nothing to change | Rewrite import paths, add aliases, update references | Requires creating _index.scss wrapper files |
| Future‑proofing | Deprecated – may be removed in future Sass releases | Recommended by Sass team; actively maintained | Part of the module system; stable |
Trade‑Offs
- Encapsulation vs Simplicity –
@useforces you to think in modules;@importfeels like a simple copy‑paste. - Performance vs Compatibility –
@usespeeds up builds and reduces output size but may break code that relies on global variables. - Learning Curve – You must learn namespace syntax (e.g.,
variables.$primary) and the rules for private members. - Tooling Support – Most modern build tools (Webpack, Vite, Gulp) support
@useout of the box, but older pipelines may need an upgrade.
Concrete Implementation
Step 1: Create a Module
Rename utils/_variables.scss to utils/variables.scss (remove the leading underscore – it’s optional but keeps the name clean).
Step 2: Import with Namespace
In your entry stylesheet (src/styles.scss) replace:
@import "utils/_variables";
with:
@use "utils/variables" as v;
Now all variables, mixins, and functions from variables.scss are accessed via the v namespace.
Step 3: Update References
Change every instance of $primary to v.$primary. For mixins, call v.mixin-name(). Example:
/* Before */
.button {
background: $primary;
}
/* After */
.button {
background: v.$primary;
}
Step 4: Verify Build Output
Run the compiler from the project root:
sass src/styles.scss:dist/styles.css --no-source-map
Check that dist/styles.css contains the expected values and that no @import directives appear in the compiled CSS.
Step 5: Measure Build Time
Use the shell time command:
time sass src/styles.scss:dist/styles.css --no-source-map
Compare the output against a baseline run with @import to ensure the build stays under the 2‑second target.
Step 6: Visual Regression Test
Run your component library (e.g., Storybook) and run a visual regression tool like Chromatic. If the UI snapshot matches the baseline, the migration did not alter appearance.
Migration Checklist
- Upgrade to Dart Sass 1.60+.
- Run
sass-migratorto flag@importusage. - Replace
@importwith@usein a subset of files. - Update all references to use the chosen namespace.
- Run build and regression tests.
- Iterate until all legacy imports are gone.
Limitations & Caveats
- Using
@use "…" as *can still pollute the global namespace; prefer explicit aliases. - Code that expects variables in the global scope (e.g.,
$primaryused by third‑party libraries) may break; wrap such libraries in a new module that re‑exports the needed names. - Some build tools may cache old CSS; clear caches after migration.
Conclusion
Adopting @use gives you a clean, maintainable architecture that protects against name collisions and reduces CSS bloat. The migration effort is justified by long‑term gains in performance and future‑proofing.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.