Compilation
|
This section documents Sass/SCSS as implemented by Dart Sass, the current official and actively maintained compiler — it is not tied to any specific book, build tool, or CSS framework (Bootstrap, Bulma, etc.). Unlike the other reference sections on this site, no single reference book underpins it: the content was generated with the assistance of AI from general knowledge of Dart Sass, and should be verified against the current official documentation at sass-lang.com before relying on it in production. Sass continues to evolve, so behaviour described here may lag the compiler you are actually running. This section’s bibliography lists the reference material consulted while preparing these pages. |
Browsers do not understand Sass. No browser has ever shipped support for $variables, @mixin, @use, or the
indented syntax, and none is planning to. Sass is a build-time language: a compiler reads your .scss/
.sass sources and emits plain .css that any browser can parse. Everything documented in this section — variables, nesting, mixins, functions, control flow, modules — exists only in the source and is gone by the
time the stylesheet is served.
This is the fundamental difference between a Sass variable and a CSS custom property (see Variables): one is erased at compile time, the other is shipped and live in the browser.
The pipeline
sass src:dist --watch"] BUNDLER["Bundler
Vite / Webpack sass-loader"] EDITOR["Editor extension
compile on save"] end SRC[".scss / .sass sources
+ partials"] COMPILER["Dart Sass compiler"] CSS["plain .css output"] MAP["source map (.css.map)"] BROWSER["Browser"] SRC --> CLI SRC --> BUNDLER SRC --> EDITOR CLI --> COMPILER BUNDLER --> COMPILER EDITOR --> COMPILER COMPILER --> CSS COMPILER -.-> MAP CSS --> BROWSER MAP -.debugging.-> BROWSER classDef core fill:#3f51b5,stroke:#1a237e,color:#fff class COMPILER core
All three entry points drive the same compiler. Choosing between them is a workflow decision, not a capability one — the CSS produced is identical.
Implementations
| Implementation | Status | Notes |
|---|---|---|
Dart Sass |
Current, official |
The reference implementation. Written in Dart, distributed as a standalone executable, as a pure-JS |
LibSass ( |
Deprecated |
The C++ implementation. Officially deprecated in 2020 and no longer maintained. It never gained the module
system ( |
Ruby Sass |
End of life |
The original implementation. Retired in 2019. |
The practical consequence: if a project still depends on node-sass, migrate it to sass. Beyond being
unmaintained, node-sass requires native compilation tied to specific Node versions, which is a recurring
source of install failures. The replacement is usually a one-line change:
npm uninstall node-sass
npm install --save-dev sass
For build-performance-sensitive projects, sass-embedded offers the same API backed by a native binary:
npm install --save-dev sass-embedded
The sass CLI
The most direct path. Install it globally or as a dev dependency:
npm install -g sass # or: brew install sass/sass/sass
Basic invocations:
# One file
sass scss/main.scss css/main.css
# A whole directory (partials are skipped automatically)
sass scss:css
# Recompile on every save
sass --watch scss:css
# Production build: compressed, no source map
sass scss:css --style=compressed --no-source-map
Useful flags
| Flag | Effect |
|---|---|
|
Recompile whenever a source file changes |
|
Output formatting; |
|
Skip the |
|
Extra directory to resolve |
|
Inline the original Sass into the source map |
|
Whether to emit CSS describing an error, so it shows up in the browser |
|
Suppress deprecation warnings originating in dependencies |
|
Only recompile files whose sources changed |
--load-path=node_modules is the one people most often need, since it lets @use "bootstrap/scss/bootstrap"
resolve without a relative path full of ../.
Output styles
.button { background: #3f51b5; color: white; }
--style=expanded (default) — readable, one declaration per line:
.button {
background: #3f51b5;
color: white;
}
--style=compressed — minified, whitespace stripped, for production:
.button{background:#3f51b5;color:white}
Dart Sass dropped the older nested and compact styles; expanded and compressed are the two that remain.
Source maps
By default the compiler writes a .css.map alongside the CSS. Browser developer tools read it and report the
original .scss file and line number for each rule, instead of a line in the generated CSS. Without one,
debugging a large compiled stylesheet means tracing rules back by hand.
Ship source maps in development; drop them in production builds (--no-source-map) unless you deliberately want
them available.
Bundler integrations
Vite
Vite supports Sass out of the box — no plugin or config needed. Install the compiler and import the file:
npm install --save-dev sass
// main.js
import './styles/main.scss';
.module.scss files are treated as CSS Modules automatically. Shared variables can be injected into every
stylesheet via config:
// vite.config.js
export default {
css: {
preprocessorOptions: {
scss: {
additionalData: `@use "src/styles/_tokens.scss" as tokens;`
}
}
}
};
Webpack
Webpack needs an explicit loader chain, applied right-to-left:
npm install --save-dev sass sass-loader css-loader style-loader
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
'style-loader', // 3. inject the CSS into the DOM
'css-loader', // 2. resolve @import/url() in the CSS
'sass-loader' // 1. compile Sass → CSS
]
}
]
}
};
For production, replace style-loader with MiniCssExtractPlugin.loader to emit a real .css file rather than
injecting styles via JavaScript.
Pin sass-loader to the Dart Sass implementation explicitly if the project has any node-sass history:
{
loader: 'sass-loader',
options: {
implementation: require('sass'),
sassOptions: { loadPaths: ['node_modules'] }
}
}
Other tooling
-
Parcel — zero-config, like Vite; install
sassand import the file. -
npm scripts — for a project with no bundler, the CLI is enough:
{ "scripts": { "css:build": "sass scss:dist/css --style=compressed --no-source-map", "css:watch": "sass --watch scss:dist/css" } } -
Framework CLIs — Angular, Next.js, Nuxt, and SvelteKit all support Sass by installing the
sasspackage; none needs further configuration in the common case.
Editor compile-on-save
For small projects or quick experiments, an editor extension avoids any build setup at all. Live Sass Compiler
for VS Code is the widely used one: it watches open .scss files and writes the compiled CSS on save, with
configurable output path and style.
This is convenient for learning and for single-page sites, but it is not a substitute for a real build step on a team project — the configuration lives in one developer’s editor settings rather than in the repository, so different machines can silently produce different output.
Where compilation fits in the wider pipeline
Sass compilation is normally one stage among several:
-
Sass → CSS (Dart Sass, covered here).
-
Autoprefixer / PostCSS — add vendor prefixes and apply other CSS transforms.
-
Minification — either Sass’s own
--style=compressed, or a dedicated minifier such ascssnano. -
Bundling and cache-busting — emit a hashed filename for long-lived caching.
Sass deliberately does not do vendor prefixing itself; that is Autoprefixer’s job, driven by a
browserslist configuration.
For the CSS-side concerns that follow compilation — critical CSS, loading strategy, and bundle size — see Runtime loading performance and Build-time performance optimization.