Organizing Sass with @use and @forward: A Practical Guide
Tired of global variable clashes and duplicate CSS? Learn how Sass’s @use and @forward modules streamline stylesheet organization, eliminate imports’ pitfalls, and give you a clean public API for your library.
06 Oct 2025, 14:47 UTC

Problem: Global Namespace Chaos
When a project grows, the old @import model quickly turns into a tangled web of variables, mixins, and selectors that all share the same global namespace. A single accidental variable rename can ripple through dozens of files, and duplicate mixins end up in the final CSS, bloating the bundle. The order in which @import statements appear becomes a fragile dependency that breaks when files are added or moved.
Thesis: The Module System Is Your New Clean Slate
Starting with Dart Sass 1.23, @use and @forward replace @import. They load a file only once, expose members under a namespace, and let you decide what becomes part of a library’s public API. The result is a predictable build, no duplicate CSS, and a clear separation between internal helpers and external consumers.
1. @use Basics – Load Once, Namespace Wisely
Consider a utilities file that holds shared colors and a button mixin. The underscore prefix (_utils.scss) keeps it private to the module system; it can’t be @use‑d directly unless you forward it.
// _utils.scss
$brand-color: #0066ff;
@mixin button-base {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
background: $brand-color;
color: #fff;
}
In your entry point you load it with a namespace. The as * modifier removes the prefix if you prefer a flatter global look.
// main.scss
@use 'utils' as *; // or @use 'utils'; for namespaced access
.btn {
@include button-base;
color: $brand-color;
}
When compiled, sass main.scss style.css will emit the button rules only once. If you had another file that also @use 'utils', Sass still loads _utils.scss> only once, preventing duplicate CSS.
2. @forward – Expose a Clean Public API
Suppose you’re building a component library. You want consumers to import components/_lib.scss but keep helper files hidden. @forward re‑exports selected members while keeping the source file private.
// _lib.scss
@forward 'utils'; // re‑exports $brand-color and button-base
@forward 'theme', hide: ($private-color); // expose theme, hide private variable
Now a consumer writes:
// page.scss
@use 'lib' as *;
.theme {
color: $brand-color; // accessible via lib namespace
}
The $private-color variable defined in theme/_private.scss is never exposed, so the consumer cannot accidentally depend on it.
3. Trade‑offs and Migration Considerations
- Verbosity vs Clarity – Namespaced access (e.g.,
utils.$brand-color) keeps origins explicit but can clutter selectors. Usingas *flattens the namespace but sacrifices traceability. - Compiler Compatibility –
@useand@forwardare only supported in Dart Sass. Projects that rely on LibSass or node‑sass must upgrade their build tooling. This may involve adjusting!defaultoverrides and updating PostCSS plugins. - Over‑forwarding – Forwarding everything from a module (e.g.,
@forward 'utils';) can re‑introduce the global namespace problem if the module contains many utilities. Carefully select what to expose.
4. Verification Checklist
- Install Dart Sass globally:
npm i -g sass. - Create a minimal
_utils.scssandmain.scssas shown above. - Run
sass main.scss style.cssand inspectstyle.cssfor a single button rule and the correct color. - Add a second file that
@use 'utils'and confirm no duplicate CSS is emitted. - Build a library with
@forwardand import it in a separate stylesheet; verify that forwarded members are accessible and private ones are not. - Run your CI pipeline to ensure it uses Dart Sass. If you use PostCSS, update the
postcss-sassplugin to a version that supports Dart Sass.
Actionable Closing
Switching to @use and @forward is a small syntax change that yields a robust, maintainable stylesheet architecture. Start by refactoring one feature module, adopt namespaced imports, and gradually expose a clean public API with @forward. Verify each step with the checklist above, and you’ll eliminate duplicate CSS, reduce build fragility, and future‑proof your front‑end code.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.