Webpack Sass / Scss compiling to separate file

Webpack is an amazing tool for transpiling and bundling JavaScript, but it can also take care of compiling Sass or Scss to static files.

get the code on github

I came across this issue while developing a prototype and not a single page app, that I needed to have a .scss file include some other files and output a .css file. I didn’t need inlined and scoped CSS like one would probably do with a single page app.

This took me surprisingly long to figure this out, mostly because there is a lot of varying information out there and not a lot of good examples that work with the up to date versions of webpack 2 RC 4 and the ExtractTextPlugin.

First of all, I recommend you globally install a recent webpack version:

npm -g install webpack@2.2.0-rc.4

Inside your project you need to install the following dependencies, remember to append the --save flag if you want them to be written to your package.json:

npm install css-loader node-sass sass-loader webpack@2.2.0-rc.4 extract-text-webpack-plugin

Now let’s say we have a project structure for a simple one-page that looks like the following (identical to the example project):

├── app.js
├── package.json
├── scss
│   ├── about
│   │   └── about.scss
│   └── main.scss
├── webpack.config.js
  • app.js contains all our cool JavaScript code
  • package.json defines our dependencies
  • scss/main.scss is our scss / sass entry point
  • webpack.config.js is our config that tells webpack what to do

If you have cloned the example repository, after running the build with webpack it should look like the following:

├── app.js
├── dist
│   ├── bundle.js
│   └── main.bundle.css
├── package.json
├── scss
│   ├── about
│   │   └── about.scss
│   └── main.scss
├── webpack.config.js

Note: Frequently developers use npm run dev or npm run build to execute the webpack command.

Notice that the directory dist including the files bundle.js and main.bundle.css have been added. The latter contains the compiled SCSS from main.scss and about.scss.

Webpack SCSS / SASS config

Typically webpack processes everything in an input file and what ever is required by that file or other files that are required from there. It builds a tree of requirements, scoops up all the JavaScript and other resources and compiles them for you. If you want to just have it look for a file, we need to use the ExtractTextPlugin to process it.

Have a look at the config for this project below:

var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: ['./app.js', './scss/main.scss'],
  output: {
    filename: 'dist/bundle.js'
  module: {

    rules: [
      your other rules for JavaScript transpiling go in here
      { // regular css files
        test: /\.css$/,
        loader: ExtractTextPlugin.extract({
          loader: 'css-loader?importLoaders=1',
      { // sass / scss loader for webpack
        test: /\.(sass|scss)$/,
        loader: ExtractTextPlugin.extract(['css-loader', 'sass-loader'])
  plugins: [
    new ExtractTextPlugin({ // define where to save the file
      filename: 'dist/[name].bundle.css',
      allChunks: true,

The config that enables us to compile SCSS/SASS from a file instead of requiring it in our JavaScript source is the loaders that refer to ExtractTextPlugin and the plugin that specifies where to write the file.

Also note that in our entry points, we specify that ./scss/main.scss should be read and then run through the rules (in this case .scss would match).

Transpiled SCSS file

Congratulations, now our .scss files that used to look like this:


// include another .scss file from a sub-directory
@import './about/about.scss';

body {
    a {
        color: magenta;


body {
    p {
        line-height: 1.5;

Should be transpiled into a plain css file:

body p {
  line-height: 1.5; }

body a {
  color: magenta; }

Thank you so much for reading this post, I hope it was useful to you! Consider following me on twitter, feedly or instagram!

If anything doesn’t work, please leave a comment and I’ll have a look!

Thank you for reading! If you have any comments, additions or questions, please leave them in the form below! You can also tweet them at me

If you want to read more like this, follow me on feedly or other rss readers

30 thoughts on “Webpack Sass / Scss compiling to separate file”

  1. Very nice tutorial.
    I have met the same problem. I have a question : what if we want css output into separate css files ?
    like this :

    ├── app.js
    ├── dist
    │ ├── bundle.js
    │ └── main.css
    ├── about
    │ │ └── about.css
    ├── package.json
    ├── scss
    │ ├── about
    │ │ └── about.scss
    │ └── main.scss
    ├── webpack.config.js

    1. you have different css for different form , in webpack during production time all css will be combined to one css & during development time it will be served from separate css file of each folder.so for production you need to combine in one css , and during development you don’t need to configure anything

  2. Thanks Sir, last 2 days will searching & identifying where and how to sass compiled files created separately using webpack.

    The way of above post will help thousand of developers who interested to learn with new technologies.

  3. Awesome. Exactly what I needed. Just “npm install –save-dev extract-text-webpack-plugin” is missing in your instructing, but this is no big deal.

        1. I’m a bit conflicted about that, since this is not a backend application.

          In a backend application you can split up between “app needs this to run” and “developer needs this to develop”.

          In a webpack focused package.json, you basically only have stuff for the developer, so if we see our build task as the application, it shouldn’t go in the dev dependencies.

  4. We can have a example to extract sass and documentation. I am trying to use VusJs vue-loader.
    Purpose: Extract sass and custom tag as contents into different files. However, both contents are split into same file.

  5. This approach in my opinion is wrong and people need to stop being fed this way of bundling.

    Your main/globals css should be separate from your pages.css. Your pages are more likely to change than your globals. You don’t want the browser to re-download the entire main.css every time you change any css file. Similarly you don’t want your about.css in the same file as your home.css, its unnecessary, especially in large applications.

    do NOT do this in your main.scss for pages:
    // include another .scss file from a sub-directory
    @import ‘./about/about.scss’;

    Rather configure Webpack to read and export both files as separate css’s:

    This way you can include page specific plugin css in your about.bundle.css . The bundling of ALL files into one is an overcompensation that most people make. You do not need only 1 css file. You should be smart and make the right decisions to leverage browser caching and modularity.

    Same goes for your JS files.

    1. The point of this tutorial is LITERALLY to bundle something to a separate file. Your statement about being wrong is invalid.

      If you think it applies to 90 out of 100 cases, that’s another thing.

      I agree people should do consistent route splitting when it helps speed up their app.

  6. In case somebody else comes across this super useful article and receives the error
    > “_ValidationError2.default(ajv.errors, name);
    . . . .
    > False”

    There was a breaking change in ‘extract-text-webpack-plugin’

    Instead of

    test: /\.css$/,
    loader: ExtractTextPlugin.extract({
    loader: ‘css-loader?importLoaders=1’,

    it must now be

    test: /\.css$/,
    loader: ExtractTextPlugin.extract({
    use: ‘css-loader?importLoaders=1’,

    The same goes for the scss. ExtractTextPlugin’s “loader” was replaced with “use”

  7. Could you explain how to intgerate font-awesome into SASS / SCSS File and build the whole css with webpack as you described above?

  8. This is a great tutorial, but in order to work with Webpack 3, you need to use `use` instead of `load` when specifying the loader for css. This worked for me:

    test: /\.css$/,
    loader: ExtractTextPlugin.extract({
    use: ‘css-loader?importLoaders=1’

  9. Your webpack.config.js in your repo and your webpack.config.js you have in your post are completely different. You seemed to have left out the entire section about the css-loader and didn’t even explain what it does…

    This article left me more confused about Webpack than I was before. Gulp is very straightforward why you would use it. This article doesn’t really show why Webpack is better that I see. If anything it’s more confusing.

  10. Great post. Easy, concise, perfect information. I’ve read about 5 different posts on this same topic, and this was the one which totally nailed it.

    Love it.

  11. Everything works fine for me but I get main.js aswell as main.css.

    So I get the correct js file for the actual js, I also get the correct css file.
    The annoying thing is I also get a js file outputted for the sass/css

    Did you have the same issue?

  12. Since webpack v4 the extract-text-webpack-plugin should not be used for css. Use mini-css-extract-plugin instead.

Leave a Reply

Your email address will not be published. Required fields are marked *