[Fixed] SASS undefined mixin error

Getting the dreaded SASS error of undefined mixin? This post will go over a few tips to fix this!

Jan 15, 2023 | Read time 8 minutes

🔔 Table of contents

Introduction

Recently, I was working on a project using SASS (https://sass-lang.com/) as their CSS processor. One issue that I came across is the dreaded “undefined mixin”:

ERROR ./styles/app.scss

SassError: Undefined mixin.

Mixins are just a simple piece of styling code that allows you to reuse across the project. You declare the mixin with the @mixin at-rule and and use it with the @include rule.

Understanding the difference between @import and @use

Both of these rules do the same thing in the end. The main difference is that @import takes everything to to a global namespace. With @use, we need to scope it to a specified namespace.

The Sass team discourages the continued use of the @import rule. Sass will gradually phase it out over the next few years, and eventually remove it from the language entirely. Prefer the @use rule instead.

Fix 1 - Check the mixin name is correct and using the correct syntax

A common reason why this error appears is that we are not following the correct syntax or mispelling the mixin.

Make sure that we are using the @use or @import keyword correctly and in the main scss file, properly use the @include keyword

To setup SASS correctly to use mixins, consider the following folder structure and go through the steps:

.
└── My-Project/
    ├── _mixins.scss
    └── styles.scss
  1. Open up the My-Project folder in VSCode. Make sure you have installed the Live SASS Compiler extension (this is just for demonstration you can use the equivalent SASS CLI).
  2. Open the _mixins.scss and add a mixin to set the theme of the page:
@mixin theme($theme: DarkGray) {
    background: $theme;
    box-shadow: 0 0 1px rgba($theme, .25);
    color: #fff;
}
  1. Open the styles.scss and add @use "mixins" :
@use "mixins" as m;

*, *::before, *::after{
    box-sizing: border-box;
    padding: 0;
    margin: 0;
}

.info {
    @include m.theme;
}

A few things to note so that we dont get the undefined mixin error:

  • Check that when we @use you have to have the as <namespace>. So in our example code, we have @use "mixins" as m;
  • Make sure to check the code ends with semicolon (;)
  • Check case sensitivity - SASS is case sensitive. For example a mixin of @mixin theme is different to @mixin Theme
  • When including the mixin with the @include keyword, make sure to include the namespace. In our example above this is @include m.theme;
  • Verify that the code for the mixin file (_mixins.scss) does not have any errors! Make sure that we are not overriding any reserved SASS keywords.

Tip: @use rule needs to be before any other rules

A stylesheet’s @use rules must come before any rules other than @forward, including style rules. However, you can declare variables before @use rules to use when configuring modules.

Whats with the underscore in the filename?

In SASS, when a file starts with a underscore this means a partial file. You might name it something like _partial.scss. The underscore lets Sass know that the file is only a partial file and that it should not be generated into a CSS file. Sass partials are used with the @use or @import rule.

Alternative to @use with @import

Now if you do not prefer to specify the namespace, you can do @use "mixins" as m;. Another way is using the @import rule.

@import "mixins";

*, *::before, *::after{
    box-sizing: border-box;
    padding: 0;
    margin: 0;
}

.info {
    @include theme;
}

Notice how we do not need to declare the namespace of “m”. Everything will be accessible globally!

Fix 2 - Verify the mixin path

Another common reason why the “undefined mixin” error comes up with using SASS is that we are not specifying the paths correctly.

When SASS compiles .scss files to css, it takes URL format not file path format. So you will have to use forward slashes (/) instead of backward slashes that you find on operation systems such as Windows (\)

This is just to ensure that it works consistently across multiple operating systems.

As an example, consider the following folder path:

.
└── My-Project/
    ├── new_styles/
    │   └── _custom_mixins.scss
    ├── _mixins.scss
    └── _styles.scss
@use "new_styles/custom_mixins" as customMixins;

*, *::before, *::after{
    box-sizing: border-box;
    padding: 0;
    margin: 0;
}

.info {
    @include customMixins.theme;
}

Notice that our new @use rule is @use "new_styles/custom_mixins" as customMixins; - we do not need to define the relative path thats required on some operating systems (eg ./)

Tip:Loading partials

Partial files let SASS know to not compile it into CSS. You can leave off the _ when importing a partial.

Undefined mixin with Bootstrap

This issue of undefined mixin comes up frequently when using Bootstrap. The problem here is that Bootstrap uses @import to import its external SCSS files.

Since SASS is moving away from @imports and recommending to use @use, if we try to extend Bootstrap with @use we will get a lot of thes “undefined mixin” errors:

Consider the following SCSS that comes with Bootstrap - importing functions and variables:

@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~/bootstrap/scss/mixins";

Now if we try to refactor with @use at-rule, we get the following:

@use "~bootstrap/scss/functions" as bootstrap_func;
@use "~bootstrap/scss/variables" as bootstrap_var;

If you complile this, you will get an error of something similar:

SassError: @use rules must be written before any other rules.

The problem is due to the fact that the @use at-rule only makes names available in the current stylesheet, as opposed to globally.

This means that the file ~bootstrap/scss/variables does not know about the functions declared in ~bootstrap/scss/functions.

With the @import rule, all the functions, mixins and variables are available globally, so it will.

In this case, there is not much we could do, but keep using @imports. To fix this the Bootstrap team needs to rewrite their codebase to structure in a way that is @use friendly!

Chasing down this issue, the Boostrap team mentions that their reasoning for not using the @use rule is not wide support in most build systems. (https://github.com/twbs/bootstrap/issues/30025#issuecomment-574825600)

Summary

In this post, I went over the SASS error of undefined mixin when compiling SASS files to CSS files. This error is usually caused by incorrect usage of the syntax (@use, @import, @include).

Make sure that we are using namespaces with @use at-rule, check for case-sensitivitiy, and not using any SASS reserved keywords

Another reason is that we are not referencing the correct path when using the mixin. SASS follows the URL format for loading modules not filepath format. This is to allow compatibility across operating systems.

👋 About the Author

G'day! I am Huy a software engineer based in Australia. I have been creating design-centered software for the last 10 years both professionally and as a passion.

My aim to share what I have learnt with you! (and to help me remember 😅)

Follow along on Twitter , GitHub and YouTube