Skip to content

[PoC] Multi Theme Support in MaterialUI - #49001

Draft
silviuaavram wants to merge 10 commits into
mui:masterfrom
silviuaavram:poc/multi-theme-support
Draft

[PoC] Multi Theme Support in MaterialUI#49001
silviuaavram wants to merge 10 commits into
mui:masterfrom
silviuaavram:poc/multi-theme-support

Conversation

@silviuaavram

@silviuaavram silviuaavram commented Aug 20, 2026

Copy link
Copy Markdown
Member

Summary

This PR explores static CSS distribution for multiple Material UI themes. Component structure and behavior remain in JavaScript, while tokens, base styles, accessibility colors, and theme-specific appearance are delivered as CSS.

The PoC covers Button and Slider, two Material UI themes, and one consumer-owned theme.

Implemented

  • Added shared foundational tokens for palette, spacing, typography, shape, elevation, and motion.
  • Added semantic forced-colors tokens based on CSS system colors.
  • Colocated authored CSS with each component:
    • css/base.css;
    • css/forced-colors.css;
    • css/themes/{polished,brutalist}.css.
  • Added theme-independent base CSS for Button and Slider.
  • Added Polished and Brutalist visual themes.
  • Added Material UI-owned forced-colors treatment shared by supplied and consumer themes.
  • Removed the components’ CSS-in-JS style bodies for the experiment.
  • Added a no-op styled-engine alias in the Vite sandbox to prevent remaining runtime style injection.
  • Added cascade layers with the following order:
    • mui.tokens;
    • mui.base;
    • mui.theme;
    • mui.a11y;
    • unlayered consumer overrides.
  • Added a consumer-owned Ocean theme built from Material UI tokens and base CSS. Importing base CSS also includes the corresponding forced-colors treatment.
  • Added buildCss.mjs to discover component CSS, apply cascade layers, and generate granular entries and theme rollups under build/css.
  • Added buildCssBundles.mjs to flatten and minify each generated theme rollup with Lightning CSS and produce source maps.
  • Exposed the generated CSS through package wildcard exports and marked CSS files as side effects.
  • Added Vite development integration that regenerates build/css when component or token CSS changes.
  • Added Vite scenarios for:
    • Polished through a whole-theme rollup;
    • Brutalist through granular component imports;
    • the consumer-owned Ocean theme.
  • Added plain HTML scenarios for:
    • a flattened whole-theme bundle;
    • a self-contained granular component stylesheet.
  • Extended the build verifier to check theme isolation, foundational CSS deduplication, generated bundles, and no-bundler CSS graphs.

Goals coverage

1. Background and goals

Goal How it is achieved and how to check
Only the selected theme is downloaded Each Vite entry imports one theme. Run the sandbox build, then inspect dist/{index,brutalist,consumer}.html and their referenced CSS; no page should contain another theme.
Tokens and base CSS are not duplicated Granular Button and Slider entries share generated token dependencies. Run the build; verify-build.mjs counts token and base signatures across each page’s loaded CSS.
Override order is deterministic Generated CSS uses ordered cascade layers, while consumer overrides are unlayered. Inspect the browser’s Styles panel to see consumer > a11y > theme > base > tokens.
Granular and rollup consumption work / uses the Polished rollup and /brutalist.html uses granular imports. After building, open cdn.html and cdn-granular.html to check both no-bundler paths.
Adding a theme does not change component JS or exports Add a theme file under each component’s css/themes/ directory. The generator discovers it and wildcard exports expose the resulting files without component JS or exports changes.

2. Next

Remaining scope

  • Validate deduplication with another tier-1 bundler such as webpack.
  • Expand coverage beyond Button and Slider.
  • Generalize the development watcher beyond the PoC component directories.
  • Decide whether granular no-bundler files also need prebundled and minified artifacts.
  • Runtime theme switching and generated scoped theme bundles remain outside the v1 scope.

@code-infra-dashboard

code-infra-dashboard Bot commented Aug 20, 2026

Copy link
Copy Markdown

Deploy preview

https://deploy-preview-49001--material-ui.netlify.app/
QR code for https://deploy-preview-49001--material-ui.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/material 0B(0.00%) 0B(0.00%)
@mui/lab 0B(0.00%) 0B(0.00%)
@mui/private-theming 0B(0.00%) 0B(0.00%)
@mui/system 0B(0.00%) 0B(0.00%)
@mui/utils 0B(0.00%) 0B(0.00%)

Details of bundle changes


Check out the code infra dashboard for more information about this PR.

@silviuaavram
silviuaavram force-pushed the poc/multi-theme-support branch from bd7c4d4 to 175dfeb Compare August 24, 2026 12:31
@github-actions github-actions Bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: out-of-date The pull request has merge conflicts and can't be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant