Skip to content

@mui/material v7: createTheme() triggers extreme Webpack memory usage during library build #46908

@nvrtmd

Description

@nvrtmd

Reproduction

Repository Link

Summary

After upgrading from MUI v6 to v7, invoking createTheme(themeOptions) in my company's design system package causes Webpack 5 builds to spike heap usage to ~2.2 GB and intermittently OOM in CI (Chromatic). Removing the createTheme call and exporting the raw themeOptions(empty object) keeps memory usage normal.

Environment

  • Package type: private design-system library in a monorepo
  • Tooling:
    • Webpack ^5.72.0, webpack-cli ^4.9.2
    • ts-loader ^9.3.0, TypeScript ^4.6.4
    • devtool: "source-map", webpack-node-externals ^3.0.0
  • UI stack:
    • @mui/material ^7.3.2, @mui/utils ^7.3.2, @mui/system ^7.3.2
    • Emotion @emotion/react 11.14.0, @emotion/styled ^11.8.1
    • React 19.0.0, React DOM 19.0.0
  • Storybook/CI:
    • Storybook 9.1.2
    • Chromatic ^6.7.0
  • Package flags:
    • "sideEffects": false
    • ESM + CJS outputs via exports map

CI symptom: Chromatic Storybook deploy fails with FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

What changed

Only the MUI upgrade (6 → 7) and the presence of createTheme(...) correlate with the memory spike. The codebase, loaders, and Webpack config are otherwise stable.

Minimal code to reproduce

// src/theme.ts
import { deepmerge } from "@mui/utils";
import { createTheme, ThemeOptions } from "@mui/material";

export const themeOptions: ThemeOptions = {
  // representative content only
  components: {
    MuiCssBaseline: deepmerge(/* baselineA */, /* baselineB */),
  },
};

// ❌ Triggers memory spike in v7
const theme = createTheme(themeOptions);

// ✅ Workaround
const theme = {};

export default theme;
  • baseline A also uses deepmerge in its styleOverrides property

Webpack excerpt with memory logging

class MemoryLoggerPlugin {
  log(label) {
    const m = process.memoryUsage();
    const mb = x => (x / 1024 / 1024).toFixed(1);
    console.log(`[mem] ${label} rss=${mb(m.rss)}MB heapUsed=${mb(m.heapUsed)}MB`);
  }
  apply(compiler) {
    compiler.hooks.beforeRun.tap("MemLog", () => this.log("beforeRun"));
    compiler.hooks.compile.tap("MemLog", () => this.log("compile"));
    compiler.hooks.afterCompile.tap("MemLog", () => this.log("afterCompile"));
    compiler.hooks.emit.tap("MemLog", () => this.log("emit"));
    compiler.hooks.done.tap("MemLog", () => this.log("done"));
  }
}
module.exports = {
  mode: "production",
  devtool: "source-map",
  module: { rules: [{ test: /\.tsx?$/, loader: "ts-loader", exclude: /node_modules/, options: { configFile: "tsconfig.build.json" } }] },
  externals: [require("webpack-node-externals")({ modulesFromFile: true })],
  plugins: [new MemoryLoggerPlugin()],
};

Observed memory

With createTheme(themeOptions)

[mem] beforeRun rss=90.3MB heapUsed=28.3MB
[mem] compile   rss=90.6MB heapUsed=28.6MB
[mem] afterCompile rss=2331.0MB heapUsed=2195.9MB
[mem] emit      rss=2331.0MB heapUsed=2195.9MB
[mem] done      rss=2334.1MB heapUsed=2198.6MB

With {}(empty object)

[mem] beforeRun rss=90.3MB heapUsed=28.5MB
[mem] compile   rss=90.6MB heapUsed=28.6MB
[mem] afterCompile rss=550.2MB heapUsed=457.4MB
[mem] emit      rss=550.2MB heapUsed=457.4MB
[mem] done      rss=550.9MB heapUsed=460.3MB

Expected

Using createTheme during a library build should not increase heap usage by ~4× or trigger OOM with default Node heap limits.

Actual

Heap jumps at afterCompile to ~2.2 GB only when createTheme is present. CI often fails with:

FATAL ERROR: Ineffective mark-compacts near heap limit
Allocation failed - JavaScript heap out of memory

Requests

  1. What is the root cause of the large heap increase when calling createTheme in v7 builds?
  2. How can this be fixed or avoided in library builds, other than increasing CI memory limits?
  3. Any guidance for memory-efficient theme composition patterns in libraries on v7?

Search keywords:

Metadata

Metadata

Assignees

Labels

customization: themeHigher level theming customizability.performancescope: systemThe system, the design tokens / styling foundations used across components. eg. @mui/system with MUIstatus: waiting for maintainerThese issues haven't been looked at yet by a maintainer.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions