MUI5: NextJS + MUI5 + SCSS Modules Boilerplate

The ultimate React front-end stack for 2022

Jeremy Tong
4 min readDec 28, 2021

Introduction

As described in the first article, we adamantly recommend the use of SCSS modules with any new React project, especially those using NextJS and MUI5.

One caveat, however, is that there isn’t a lot of information describing this approach and how one should properly setup their repo as well as their VSCode workflow. Probably why this stack hasn’t become more popular.

Here, I’ll share the culmination of my findings from a week’s worth of deep research into NextJS and Material-UI docs. I recently used this stack in building a crypto calculator web app (90+ Lighthouse score in all categories), which was forked to create the next-mui5-boilerplate code shared in this article.

TL;DR

Checkout next-mui5-boilerplate, a comprehensive starting point for a NextJS Typescript project.

SASS Variable Injection

**note, this approach only works if your MUI5 theme is not dynamic

The most notable challenge of using CSS/SCSS modules with MUI5 is interchanging variables between the MUI5 theme.js file and your SCSS files.

It’s well known that you can use the :export directive in SCSS module files to allow SCSS variables to be imported in any JS file.

It is much more challenging to import variables from a JS file into a SCSS module file. One option I explored was to include the js-to-styles-var-loader webpack loader, but I wasn’t able to get it working with the NextJS build in SASS loader (even with a lot of deliberation).

MUI5 is powered by a ThemeProvider, which uses the variables specified in a theme object. Notice line 28, this is how you’d assign a value that is dependent on a MUI5 theme function (e.g. spacing === 8px).

Instead, I settled on this solution which uses node-sass-utils and preloads JS variables into a SCSS object map on webpack compile time.

This solution is extensible to multiple files, but for the MUI5 use case, you should only need the theme.js file as shown above.

Also, while the rest of the project is Typescript, the files you import into your next.config.js file in the require() statement must be vanilla Javascript. There are some complex solutions that overcome this limitation, but I found this to work best for me.

SCSS Variable Usage

In the styles folder of your Next project, you should include your non-module scoped SCSS files. These can be imported to any SCSS file via the @import rule (e.g. @import variables). Here are the essential ones I use in my projects.

  1. _global.scss — entry point for SCSS files, import this into the _app.tsx page.
  2. _variables.scss — common variables to use across SCSS module files such as font-size or colors. This is where you can redeclare your injected theme.js variables.
Here, I create some aliases for some commonly used variables derived from theme.js

3. _mixins.scssSCSS mixin functions to help with breakpoints. I included a @mixin screen($size) in my boilerplate code which replicates the media breakpoint functions in MUI5.

Other Miscellaneous Config

A couple more things are required to get this all working.

  1. Emotion Cache Not a SCSS modules specific thing, but requires some setup in the createEmotionCache.ts, _document.tsx, and _app.tsx file to make sure NextJS SSR works with MUI5’s Emotion styling engine
  2. Layout FOUC Hack With the way that SCSS modules interact with the NextJS project, there is currently an open issue on FOUC (flickering on unmounted component, i.e. weird un-styled behavior on initial page load). This layout.tsx file forces a client-side mounted render to prevent this behavior without any noticeable performance hit.
  3. Stylelint You can manage your SCSS style conventions, such as with .stylelintrc.json.

Workflow

If you’re working with VSCode, these are my recommended extensions for use with this stack.

  1. CSS-to-JSS — This extension allows you to convert between JSS style objects and CSS. Immensely useful if you want to test your styles first in .jsx before moving them to the .module.scss files.
  2. CSS Navigation — Cmd-click support for class assignments in .jsx files (jump directly to the class declaration in your .module.scss file). Overrides the default of linking you to the typescript definitions.
  3. SCSS Formatter — Prettier support for SCSS
  4. SCSS IntelliSense — Autocompletion
  5. Stylelint
  6. tsImportSorter — This extension allows you to sort and customize your import order. I like the following config which moves SCSS module imports to the top.

Bonus Unrelated

I included Google Analytics and SEO configuration examples in the boilerplate code, since I feel that those two projects also require a bit of setup and are useful in any React project.

Final Thoughts

I’m going to enthusiastically say again that this is the stack you should be using for modern front-end web apps. It takes inspiration from many of the codebases I’ve worked on over the last few years, and has been the most enjoyable development experience for front-end work so far (see our other NexusJS Node Server article for a back-end recommendation to accompany this stack).

Sign up to discover human stories that deepen your understanding of the world.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Jeremy Tong
Jeremy Tong

Written by Jeremy Tong

Startup-Focused Software Developer

Responses (1)

Write a response