Overview
sass-loader compiles Sass/SCSS to CSS. It uses Dart Sass (recommended), Node Sass, or Sass Embedded as the compiler. Use it with css-loader and style-loader to add Sass support to your webpack project.
This is an external loader maintained by the webpack team. Install it from npm to use in your webpack configuration.
Installation
npm (Dart Sass - Recommended)
yarn
pnpm
npm install -D sass-loader sass
Node Sass is deprecated. Use Dart Sass (sass package) instead.
Basic Usage
webpack.config.js
app.js
styles.scss
module . exports = {
module: {
rules: [
{
test: / \. s [ ac ] ss $ / i ,
use: [
'style-loader' ,
'css-loader' ,
'sass-loader'
]
}
]
}
};
Loader Chain Order
Loaders execute from right to left:
sass-loader - Compiles Sass to CSS
css-loader - Resolves CSS imports and URLs
style-loader - Injects CSS into DOM
use : [ 'style-loader' , 'css-loader' , 'sass-loader' ]
Options
implementation
Specify which Sass implementation to use:
const sass = require ( 'sass' );
module . exports = {
module: {
rules: [
{
test: / \. s [ ac ] ss $ / i ,
use: [
'style-loader' ,
'css-loader' ,
{
loader: 'sass-loader' ,
options: {
implementation: sass
}
}
]
}
]
}
};
sassOptions
Pass options to the Sass compiler:
{
loader : 'sass-loader' ,
options : {
sassOptions : {
indentWidth : 2 ,
includePaths : [ 'node_modules' , 'src/styles' ],
outputStyle : 'compressed'
}
}
}
outputStyle: 'compressed' is ignored in Dart Sass. Use CSS minifier plugins instead.
sourceMap
Enable source maps:
{
loader : 'sass-loader' ,
options : {
sourceMap : true
}
}
additionalData
Prepend/append Sass code to every file:
{
loader : 'sass-loader' ,
options : {
additionalData : `
$primary: #3498db;
$secondary: #2ecc71;
@import "variables";
`
}
}
Or use a function:
{
loader : 'sass-loader' ,
options : {
additionalData : ( content , loaderContext ) => {
// Add variables based on file path
const { resourcePath } = loaderContext ;
if ( resourcePath . includes ( 'components' )) {
return '@import "component-variables"; \n ' + content ;
}
return content ;
}
}
}
Advanced Configuration
Import Paths
Configure where Sass looks for imports:
{
loader : 'sass-loader' ,
options : {
sassOptions : {
includePaths : [
path . resolve ( __dirname , 'src/styles' ),
path . resolve ( __dirname , 'node_modules' )
]
}
}
}
// Now you can import without relative paths
@import 'variables' ; // Looks in includePaths
@import 'bootstrap/scss/bootstrap' ; // From node_modules
Webpack Resolve Alias
Use webpack resolve with ~ prefix:
module . exports = {
resolve: {
alias: {
'@styles' : path . resolve ( __dirname , 'src/styles' )
}
},
module: {
rules: [
{
test: / \. scss $ / ,
use: [ 'style-loader' , 'css-loader' , 'sass-loader' ]
}
]
}
};
@import '~@styles/variables' ;
@import '~bootstrap/scss/bootstrap' ;
Global Variables
{
loader : 'sass-loader' ,
options : {
additionalData : `
$env: ' ${ process . env . NODE_ENV } ';
$api-url: ' ${ process . env . API_URL } ';
`
}
}
.debug-info {
@if $env == 'development' {
display : block ;
} @else {
display : none ;
}
}
Common Patterns
With PostCSS
{
test : / \. scss $ / ,
use : [
'style-loader' ,
'css-loader' ,
'postcss-loader' ,
'sass-loader'
]
}
With CSS Modules
{
test : / \. module \. scss $ / ,
use : [
'style-loader' ,
{
loader: 'css-loader' ,
options: {
modules: true ,
importLoaders: 2
}
},
'postcss-loader' ,
'sass-loader'
]
}
Development vs Production
module . exports = {
mode: 'development' ,
module: {
rules: [
{
test: / \. scss $ / ,
use: [
'style-loader' ,
{
loader: 'css-loader' ,
options: {
sourceMap: true
}
},
{
loader: 'sass-loader' ,
options: {
sourceMap: true
}
}
]
}
]
}
};
Bootstrap Integration
{
loader : 'sass-loader' ,
options : {
sassOptions : {
includePaths : [ 'node_modules' ]
}
}
}
// Custom Bootstrap variables
$primary : #007bff ;
$enable-rounded : false ;
// Import Bootstrap
@import 'bootstrap/scss/bootstrap' ;
// Custom styles
.my-component {
@extend .btn ;
@extend .btn-primary ;
}
Limit Scope
{
test : / \. scss $ / ,
include : path . resolve ( __dirname , 'src' ),
use : [ 'style-loader' , 'css-loader' , 'sass-loader' ]
}
Cache Compilation
Webpack 5 caches automatically, but you can configure it:
module . exports = {
cache: {
type: 'filesystem'
},
module: {
rules: [
{
test: / \. scss $ / ,
use: [ 'style-loader' , 'css-loader' , 'sass-loader' ]
}
]
}
};
Thread Loader
For large projects:
npm install -D thread-loader
{
test : / \. scss $ / ,
use : [
'style-loader' ,
'thread-loader' ,
'css-loader' ,
'sass-loader'
]
}
Common Issues
Issue: Cannot Find Module
Error:
Can't find stylesheet to import.
Solution: Use ~ prefix for node_modules or configure includePaths:
@import '~bootstrap/scss/bootstrap' ; // Correct
@import 'bootstrap/scss/bootstrap' ; // May fail
Issue: Compilation Errors
Error:
Solution: Check Sass syntax and ensure all variables are defined:
// Define before use
$primary-color : #3498db ;
.header {
color : $primary-color ;
}
Issue: Slow Compilation
Solution:
Limit scope with include
Enable caching
Use Dart Sass instead of Node Sass
Minimize use of @import (use @use instead)
Issue: Source Maps Not Working
Solution: Enable source maps in all loaders:
{
test : / \. scss $ / ,
use : [
'style-loader' ,
{
loader: 'css-loader' ,
options: { sourceMap: true }
},
{
loader: 'sass-loader' ,
options: { sourceMap: true }
}
]
}
Dart Sass vs Node Sass
Dart Sass (Recommended)
Node Sass (Deprecated)
Feature Dart Sass Node Sass Performance Good Faster Maintenance Active Deprecated Features Latest Limited Compatibility Better Issues with Node versions
Node Sass is deprecated and not recommended. Migrate to Dart Sass.
Modern Sass Features
Using @use and @forward
// _variables.scss
$primary : #3498db ;
$secondary : #2ecc71 ;
// styles.scss
@use 'variables' as vars ;
.header {
color : vars . $primary ;
}
Modules
@use 'sass:math' ;
@use 'sass:color' ;
.box {
width : math . div ( 100 % , 3 );
background : color . scale ( #3498db , $lightness: 20 % );
}
Resources