Sass Modules — @use and @forward for Namespaced Imports
In this tutorial, you will learn about Sass Modules. We cover key concepts, practical examples, and best practices to help you master this topic.
Sass modules use @use to import files with automatic namespacing, @forward to re-export members, and underscore-prefixed private members for encapsulated module design.
What You'll Learn
You will learn how to use @use for namespaced imports, configure namespaces, use @forward to create barrel files, and write private members.
Why It Matters
Modules prevent naming conflicts. DodaTech's library uses @use to import theme modules with clear namespaces, avoiding variable collisions across team contributions.
Real-World Use
The shared Sass library across DodaTech products uses @forward to create a single public API point, while keeping internal variables private.
flowchart LR
A[Partials & Import] --> B[Modules]
B --> C[@use]
B --> D[@forward]
B --> E[Namespaces]
B --> F[Private Members]
style B fill:#c69,stroke:#c69,color:#fff
style C fill:#22c55e,stroke:#16a34a,color:#fff
@use Basics
// _colors.scss
$primary: #7c3aed;
$secondary: #64748b;
$danger: #ef4444;
// main.scss
@use "colors";
.button {
background: colors.$primary;
color: white;
}
.alert {
border-color: colors.$danger;
}
Expected output: All variables are accessed with the module namespace colors.$variable. The compiled CSS has the actual color values.
Custom Namespaces
@use "colors" as c;
@use "typography" as typo;
.button {
background: c.$primary;
font-family: typo.$font-family;
}
Expected output: Shorter namespaces (c.$primary instead of colors.$primary) for frequently used modules.
Without Namespace
// Import without namespace (use carefully)
@use "colors" as *;
.button {
background: $primary; // Direct access
}
Expected output: Variables are available without a namespace prefix. This can cause naming conflicts.
@forward
// _index.scss (barrel file)
@forward "colors";
@forward "typography";
@forward "mixins";
// main.scss
@use "index" as *;
.button {
background: $primary;
@include respond-to(md) {
width: 50%;
}
}
Expected output: The @forward re-exports all members from the sub-modules. Using @use "index" as * makes everything available.
Private Members
Members starting with - or _ are private and not accessible outside the module:
// _config.scss
$public-color: #7c3aed; // Public
$-private-color: #333; // Private (not exported)
@function public-fn() {
@return $-private-color;
}
@function -private-fn() {
@return "hidden";
}
@use "config";
.foo {
color: config.$public-color; // Works
// color: config.$-private-color; // Error: private
}
Expected output: Only public members are accessible from outside the module.
Configured Modules
// _theme.scss
$primary: blue !default;
$danger: red !default;
.button {
background: $primary;
}
// main.scss
@use "theme" with (
$primary: #7c3aed,
$danger: #dc2626
);
Expected output: The module uses the configured values (purple primary, red danger) instead of the defaults.
Mixed @import and @use
You cannot use @import and @use for the same file. Migrate towards @use:
// Deprecated approach — avoid
@import "variables"; // Global
// Modern approach
@use "variables"; // Namespaced
Expected output: @use is the recommended approach. @import is deprecated in Dart Sass.
Common Mistakes
1. Using @import After @use
Once @use is used anywhere in a file, @import is not allowed in that file. Be consistent.
2. Forgetting Namespace Prefix
After switching to @use, variables require the namespace prefix unless using as *.
3. Circular @use Dependencies
Module A uses B, and B uses A. Sass detects and errors on circular dependencies.
4. Not Using @forward for Libraries
Library authors should use @forward to expose a clean public API from an index file.
5. Private Members Still Visible in Compiled CSS
Private Sass members compile to CSS normally. Privacy is only at the Sass module level.
Practice Questions
How do you import a module with a custom namespace?
@use "module" as alias;then access members withalias.$variable.What is the difference between @use and @forward? @use imports a module with a namespace. @forward re-exports a module's members for other files to @use.
How do you make a variable private to a module? Prefix the variable name with
-or_(e.g.,$-private).How do you configure a module's default variables on import? Use
@use "module" with ($var: value);to override defaults.Can @use and @import be used in the same file? No. Once @use is used, @import is not allowed in any file in that compilation.
Challenge
Create a theme library with three modules (_colors.scss, _typography.scss, _spacing.scss) and a _index.scss that @forwards them. Create a main.scss that @uses the index and styles a card component using the library.
FAQ
Mini Project
Create a modular Sass library with four files: _variables.scss, _mixins.scss, _functions.scss, and _index.scss (which forwards all three). Write a main.scss that @uses the index and builds a button component using the library's members.
What's Next
Learn Sass Mixins Basics for reusable style blocks. Then explore Sass Mixin Arguments for parameterized mixins.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro