Skip to content

Sass with Next.js

Sass extends plain CSS with variables, nesting, mixins, and other features, and Next.js supports it with zero extra configuration beyond installing one package. This lesson covers using Sass, including alongside CSS Modules.

Sass Support Out of the Box

Once the sass package is installed as a dependency, Next.js automatically compiles any .scss (or .sass) file the same way it handles .css files — including as global stylesheets or as CSS Modules by using the .module.scss naming convention.

Sass's most commonly used features — nesting selectors, defining reusable variables, and writing mixins for repeated patterns — reduce a lot of the repetition that plain CSS requires, especially in larger stylesheets.

// npm install -D sass

/* Button.module.scss */
$primary-color: #0070f3;

.button {
  background: $primary-color;
  padding: 8px 16px;

  &:hover {
    background: darken($primary-color, 10%);
  }
}

// Button.tsx
import styles from "./Button.module.scss";
<button className={styles.button}>Click</button>

This works exactly like a .module.css file, but with Sass's variables and nesting syntax available.

Sass Feature Quick Reference

$variable: value;              // variables
.parent { .child { ... } }    // nesting
@mixin name($arg) { ... }      // reusable style blocks
@include name(value);          // using a mixin
@use "./partial" as p;         // importing another Sass file
  • $variable defines a reusable value, similar in spirit to a CSS custom property but resolved at compile time.
  • Nesting selectors mirrors your HTML structure, reducing repeated parent selectors.
  • @mixin/@include let you define and reuse a whole block of styles with arguments.
  • @use is the modern way to split styles across multiple .scss partial files.

Sass Cheat Sheet

Core Sass features and Next.js-specific notes.

Feature Syntax
Variable $color: #0070f3;
Nesting .card { .title { ... } }
Mixin @mixin flex-center { ... }
Include a mixin @include flex-center;
Import a partial @use "./variables" as v;
Scoped Sass Module Name the file *.module.scss

Writing and Using a Mixin

Mixins are useful for style patterns you repeat across many components, like a common flex-centering layout, avoiding the need to retype the same handful of declarations everywhere.

/* _mixins.scss */
@mixin flex-center($gap: 0) {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: $gap;
}

/* Card.module.scss */
@use "./mixins" as m;

.wrapper {
  @include m.flex-center(8px);
}

Sass vs. Tailwind: Two Different Philosophies

Sass keeps you writing traditional CSS rules with superpowers layered on top, while Tailwind replaces custom CSS almost entirely with utility classes in your markup. Both are fully supported in Next.js, and the choice mostly comes down to whether your team prefers writing stylesheets or composing utility classes.

Common Mistakes

  • Forgetting to install the sass package, causing .scss files to fail to compile.
  • Nesting selectors too many levels deep, producing overly specific, hard-to-override CSS.
  • Using the older @import syntax instead of the modern @use/@forward module system.
  • Mixing Sass variables and CSS custom properties inconsistently across a project.

Key Takeaways

  • Next.js supports Sass automatically once the sass package is installed.
  • .module.scss files work as scoped CSS Modules, just like .module.css.
  • Variables, nesting, and mixins are Sass's most commonly used features.
  • @use is the modern, recommended way to share styles across multiple .scss files.
  • Sass and Tailwind represent different philosophies; both are fully supported in Next.js.

Pro Tip

If you're adopting Sass specifically for design tokens (colors, spacing), consider whether CSS custom properties would serve just as well with less tooling — Sass variables are compile-time only, while CSS custom properties can also be read and changed at runtime, which is useful for things like theme switching.