Jesse A. Green / notebook

Material UI (MUI) Administrator & Developer Guide

Generated May 2026 from mui/material-ui at 3dcaf4b

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

1. Architecture Overview

Material UI is a monorepo hosting 12 publishable npm packages that together form a layered React component library implementing Google's Material Design. The repository at mui/material-ui (commit 3dcaf4b2, 2026-04-18) contains 41,043 files across 14.7 million source characters, organized as a pnpm workspace with Lerna + Nx for task orchestration.

Package Dependency Chain

@mui/types
    └── @mui/utils
         └── @mui/private-theming
              └── @mui/system
                   ├── @mui/styled-engine (Emotion, default)
                   │    └── @emotion/react + @emotion/styled
                   └── @mui/styled-engine-sc (styled-components, optional)
                        └── styled-components
                   └── @mui/material (86 components)
                        ├── @mui/lab (incubator)
                        ├── @mui/icons-material (2,100+ SVG icons)
                        ├── @mui/material-nextjs (Next.js SSR)
                        └── @mui/material-pigment-css (zero-runtime CSS)

Component Inventory

Package Published Name Contents
packages/mui-material @mui/material 86 React components, 4 hooks, utility functions, 60+ locales, color palettes
packages/mui-system @mui/system Theming engine, sx prop, styled(), layout components (Box, Grid, Stack, Container), breakpoints, spacing, CSS variables provider
packages/mui-utils @mui/utils ~50 low-level utilities (debounce, deepmerge, composeClasses, fork ref, focus management, etc.)
packages/mui-lab @mui/lab Incubator: LoadingButton, Masonry, Timeline, TabContext/TabList/TabPanel, plus deprecated date picker re-exports
packages/mui-icons-material @mui/icons-material 2,100+ auto-generated SVG icon components in 5 variants (Filled, Outlined, Rounded, Sharp, TwoTone)
packages/mui-styled-engine @mui/styled-engine Emotion adapter: styled(), keyframes, css, GlobalStyles, StyledEngineProvider
packages/mui-styled-engine-sc @mui/styled-engine-sc styled-components adapter (drop-in replacement)
packages/mui-types @mui/types TypeScript utility types: OverridableComponent, DistributiveOmit, OverridableStringUnion
packages/mui-private-theming @mui/private-theming Minimal ThemeProvider + useTheme (internal, lowest layer)
packages/mui-codemod @mui/codemod jscodeshift + postcss migration transforms (v5→v6→v7→v9 and deprecation codemods)
packages/mui-material-nextjs @mui/material-nextjs Next.js App/Pages Router cache providers (v13, v15 variants)
packages/mui-material-pigment-css @mui/material-pigment-css Zero-runtime Pigment CSS integration (PigmentContainer, PigmentGrid, PigmentStack)
packages/mui-envinfo @mui/envinfo CLI environment diagnostic tool
packages/mui-core-downloads-tracker @mui/core-downloads-tracker Empty package for npm download counting

Note

The @mui/icons-material/lib directory alone accounts for 10,750 files and 8.5 million characters (58% of the repo by size). Each icon is a thin wrapper around createSvgIcon() with the SVG path data inlined.

Technology Stack

Layer Technology Version
Language TypeScript 5.9.3
Runtime React ^17.0.0 || ^18.0.0 || ^19.0.0
Package manager pnpm 10.33.0
Monorepo orchestration Lerna + Nx 9.0.7 / 20.8.4
Build Babel (JS output) + tsc (declarations only) 7.29.0
Default styling engine Emotion @emotion/react + @emotion/styled
Alternative styling engine styled-components via @mui/styled-engine-sc
Test runner Vitest ^4.0.13
Browser testing Playwright 1.59.1
E2E testing Playwright + @testing-library/react -
Bundler (docs site) Next.js ^15.5.14
Linting ESLint 10.1.0 + Stylelint 17.6.0 + markdownlint-cli2 0.22.0 -
Formatting Prettier 3.8.1

Data Flow: Component Rendering

User JSX:
  <Button variant="contained" sx={{ m: 2 }}>Click</Button>
     │
     ▼
DefaultPropsProvider resolves theme defaults:
  theme.components.MuiButton.defaultProps → merged with user props
     │
     ▼
styled() (via @mui/styled-engine / Emotion):
  Applies base styles + variant-based conditional styles
  Processes sx prop via styleFunctionSx (shorthand → CSS → responsive)
     │
     ▼
useSlot() resolves slot composition:
  Root slot: applies component prop (polymorphism)
  Named slots: merge slotProps (className, style, sx, event handlers)
     │
     ▼
composeClasses() generates CSS class names:
  MuiButton-root, MuiButton-contained, MuiButton-containedPrimary
     │
     ▼
React renders final DOM with Emotion-injected styles

2. System Requirements

Requirement Value
Node.js >= 22.18.0
pnpm 10.33.0 (enforced via packageManager field)
React ^17.0.0 || ^18.0.0 || ^19.0.0
TypeScript 5.9.3 (development)
OS Any (Linux, macOS, Windows)
Disk ~500 MB for full clone + node_modules

Development Dependencies (key)

Package Version Purpose
@babel/core 7.29.0 JS compilation
vitest ^4.0.13 Test runner
vite ^7.2.2 Test/build tooling
playwright 1.59.1 Browser automation
eslint 10.1.0 Linting
prettier 3.8.1 Code formatting
lerna 9.0.7 Monorepo versioning/publishing
nx 20.8.4 Task orchestration
concurrently 9.2.1 Parallel script execution
cross-env 10.1.0 Cross-platform env vars
tsx 4.21.0 TypeScript execution
dotenv 17.4.0 .env loading

3. Configuration Reference

Theme Configuration Object

The createTheme() function accepts the following top-level keys:

Key Type Purpose
palette object Colors: primary, secondary, error, warning, info, success, text, background, divider, action, mode
typography object/function Font families, sizes, weights for h1-h6, subtitle1-2, body1-2, button, caption, overline
spacing number/function Base spacing unit (default: 8px)
breakpoints object Responsive breakpoint values and unit
shape object borderRadius (default: 4)
transitions object Duration, easing curves
zIndex object z-index values for mobileStepper, fab, speedDial, appBar, drawer, modal, snackbar, tooltip
components object Per-component defaultProps, styleOverrides, and variants
shadows array 25 shadow values (0-24 elevation levels)
mixins object toolbar mixin for AppBar height
direction 'ltr' | 'rtl' Text direction

Default Breakpoints

Key Default (px)
xs 0
sm 600
md 900
lg 1200
xl 1536

Breakpoint helpers: theme.breakpoints.up('sm'), down('md'), between('sm', 'lg'), only('md'), not('xs').

Default Palette (Light Mode)

Token Default Value
primary.main #1976d2
primary.light computed via lighten()
primary.dark computed via darken()
primary.contrastText computed via getContrastRatio()
secondary.main #9c27b0
error.main #d32f2f
warning.main #ed6c02
info.main #0288d1
success.main #2e7d32
text.primary rgba(0,0,0,0.87)
text.secondary rgba(0,0,0,0.6)
background.default #fff
background.paper #fff
divider rgba(0,0,0,0.12)

The sx Prop Configuration Map

The sx prop is powered by defaultSxConfig.js which maps shorthand properties to CSS properties, theme keys, and transform functions:

Category Shorthands
Spacing m, mt, mr, mb, ml, mx, my, p, pt, pr, pb, pl, px, py, margin*, padding* (including logical properties: marginInline, paddingBlock, etc.)
Palette color, bgcolor (background-color), backgroundColor
Borders border, borderTop, borderRight, borderBottom, borderLeft, borderColor, borderRadius
Display display, overflow, textOverflow, visibility, whiteSpace
Flexbox flexBasis, flexDirection, flexWrap, justifyContent, alignItems, alignContent, order, flex, flexGrow, flexShrink, alignSelf, justifyItems, justifySelf
Grid gap, columnGap, rowGap, gridColumn, gridRow, gridAutoFlow, gridAutoColumns, gridAutoRows, gridTemplateColumns, gridTemplateRows, gridTemplateAreas, gridArea
Positions position, zIndex, top, right, bottom, left
Shadows boxShadow → maps to theme.shadows
Sizing width, maxWidth, minWidth, height, maxHeight, minHeight, boxSizing
Typography fontFamily, fontSize, fontStyle, fontWeight, letterSpacing, textTransform, lineHeight, textAlign, typography

Important

Each spacing shorthand resolves values through theme.spacing(). Numbers are multiplied by the base (default 8px). Strings pass through as-is. Palette shorthands resolve dot-notation paths (e.g., 'primary.main') against theme.palette.

Environment Variables

Variable Context Purpose
GITHUB_TOKEN Release Required for changelog generation
CIRCLE_TOKEN CI CircleCI pipeline triggers
CIRCLE_BRANCH CI Current branch in CircleCI
NODE_ENV Build/Test production for docs build, regression tests
CI Test 'true' enables a11y tree exclusion checks
TEST_SCOPE Test node or browser — controls which Vitest suite runs
VITEST_BROWSERS Test firefox,webkit — additional browser targets
TZ Test UTC — timezone for test suite
UV_THREADPOOL_SIZE Build 64 — parallelism for icon build
DOCS_STATS_ENABLED Docs true — enables webpack bundle analyzer
NEXT_PUBLIC_MUI_LICENSE Docs MUI X license key for docs site
NETLIFY_SITE_NAME Deploy Netlify site identifier
DEPLOY_ENV Docs Deployment environment flag
SOURCE_CODE_REPO Docs Source repo URL for "edit this page" links
PLAYWRIGHT_TEST_BASE_URL Test Base URL for Playwright tests
LIB_VERSION Docs Library version displayed on docs site
CONTEXT Build Netlify build context
DEPLOY_PRIME_URL Build Netlify deploy preview URL
HEAD Build Git HEAD reference

Codemod CLI Reference

npx @mui/codemod <transform> <paths...> [options]
Option Default Description
--dry false Dry run — no file changes
--parser tsx Parser: babel, ts, tsx, flow
--print false Print transformed output to stdout
--jscodeshift - Pass-through flags to jscodeshift
--packageName @mui/material Target package name for transforms

Available transforms:

Category Transforms
v6.0.0 all, grid-v2-props, styled, sx-prop, system-props, theme-v6
v7.0.0 all, grid-props, input-label-size-normal-medium, lab-removed-components, theme-color-functions
v9.0.0 system-props
Deprecations accordion-props, alert-classes, autocomplete-props, avatar-group-props, backdrop-props, button-classes, card-header-props, checkbox-props, chip-classes, dialog-props, divider-props, drawer-props, filled-input-props, input-props, linear-progress-classes, menu-item-props, mobile-stepper-props, modal-props, outlined-input-props, pagination-props, popover-props, popper-props, select-props, skeleton-props, slider-props, snackbar-props, step-content-props, switch-props, table-sort-label-props, text-field-props, toggle-button-group-props, tooltip-props, typography-props

4. Deployment & Scaling

Bundle Optimization

MUI packages declare "sideEffects": false for tree-shaking. Recommended import patterns:

// Path import (always tree-shakeable)
import Button from '@mui/material/Button';

// Named import (requires bundler tree-shaking support)
import { Button } from '@mui/material';

Icons are the biggest bundle risk. Each @mui/icons-material icon is a separate module with CJS + ESM dual format:

{
  "require": "./Delete.js",
  "import": "./esm/Delete.js",
  "default": "./esm/Delete.js"
}

Bundling Test Matrix

The repository tests bundling compatibility with:

Bundler Version Config
esbuild 0.25.0 ESM + CJS
webpack 5 via Next.js 14.2.35 React 18
webpack 4 via Next.js 14.2.35 React 17
Vite 5.4.21 ESM
Snowpack 3.8.8 ESM
Gatsby 5.13.7 webpack
Node CJS native require()
Node ESM native import

Server-Side Rendering

Next.js Integration

@mui/material-nextjs provides cache providers for both routing modes:

  • App Router (v15): AppRouterCacheProvider from @mui/material-nextjs/v15-appRouter
  • Pages Router (v15): Provider from @mui/material-nextjs/v15-pagesRouter
  • Pages Router (v13): Provider from @mui/material-nextjs/v13-pagesRouter
  • App Router (v13): Provider from @mui/material-nextjs/v13-appRouter

Express SSR

Requires @emotion/server for critical CSS extraction:

  1. Create a shared Emotion cache instance
  2. Create an Emotion server with createEmotionServer(cache)
  3. Render to string: renderToString(<CacheProvider value={cache}><App /></CacheProvider>)
  4. Extract chunks: extractCriticalToChunks(html)
  5. Construct style tags: constructStyleTagsFromChunks(chunks)

Pigment CSS (Zero-Runtime)

@mui/material-pigment-css provides build-time CSS extraction via Pigment CSS:

  • Eliminates Emotion runtime from production bundles
  • Requires bundler plugin: @pigment-css/nextjs-plugin or @pigment-css/vite-plugin
  • Provides replacement components: PigmentContainer, PigmentGrid, PigmentStack
  • Current version: @pigment-css/react 0.0.30 (experimental)

Note

Pigment CSS is experimental. The API may change. Pin the version with resolutions: "@pigment-css/*": "0.0.30".


5. Operations

Development Workflow

# Clone and install
git clone https://github.com/mui/material-ui.git
cd material-ui
pnpm install

# Start docs site (dev mode)
pnpm docs:dev

# Run unit tests
pnpm test:unit

# Run browser tests
pnpm test:browser

# Run e2e tests
pnpm test:e2e

# Run visual regression tests
pnpm test:regressions

# Lint
pnpm eslint
pnpm stylelint
pnpm markdownlint
pnpm valelint

# Format
pnpm prettier

Tip

The docs dev server requires significant memory. The production build uses NODE_OPTIONS=--max_old_space_size=8192.

Testing Architecture

Test Type Command Runner Scope
Unit/Integration pnpm test:unit Vitest (TZ=UTC) All packages
Node-scoped pnpm test:node Vitest (TEST_SCOPE=node) Server-side logic
Browser-scoped pnpm test:browser Vitest + Playwright browsers Browser-specific behavior
E2E (website) pnpm test:e2e Playwright Docs site navigation, links
Visual regression pnpm test:regressions Playwright screenshots Pixel-perfect rendering
Bundle size test/bundle-size/ Custom Package size tracking
Module resolution test/moduleResolution/ Node CJS + ESM Import path validation

Custom test matchers:

  • toWarnDev(message) — asserts console.warn is called with the expected message
  • toErrorDev(message) — asserts console.error is called with the expected message

Test helpers:

  • @mui/internal-test-utils/createRenderer — creates a render function with cleanup
  • @testing-library/react — DOM queries and interactions
  • Coverage: Istanbul via @vitest/coverage-v8, HTML report at coverage/index.html

Tip

Use pnpm use-react-version <version> to test against different React versions: stable, next, experimental, latest, ^17.0.0.

Release Process

  1. Version bump: pnpm release:version (Lerna — no changelog, no push, no git tag)
  2. Generate changelog: pnpm release:changelog (requires GITHUB_TOKEN)
  3. Open PR: Create a PR with version + changelog changes
  4. Merge + publish: After merge, trigger the GitHub Actions publish workflow at github.com/mui/material-ui/actions/workflows/publish.yml
  5. Hotfix: Branch release/<PATCH_VERSION> from last tag, cherry-pick, publish with --dist-tag for legacy/canary

Docs Deployment

  • Framework: Next.js ^15.5.14
  • Hosting: Netlify (material-ui.netlify.app)
  • Translation: Crowdin (crowdin.com/project/material-ui-docs)
  • Branches: latest = mui.com, next = next.mui.com, v*.x = v*.mui.com
  • Deploy repo: material-ui-docs (separate, FETCH_HEAD:latest branch)
  • Build: pnpm docs:build (Next.js export)
  • Deploy: pnpm docs:deploy (pushes to deploy repo)

CI/CD

  • CircleCI: Primary CI — unit tests, browser tests, visual regressions, bundle size checks
  • GitHub Actions: Publish workflow, PR checks
  • Netlify: Deploy previews for docs PRs, edge functions for redirects
  • Performance profiling: CircleCI profile workflow, results at frontend-public.mui.com/test-profile/:job-number

6. Performance

Bundle Size

MUI components are individually importable. Each component is a separate module. Key size factors:

  • Icons: @mui/icons-material contains 10,750 module files. Always import specific icons, never the package root.
  • Tree-shaking: All packages declare sideEffects: false. Use a bundler that respects this (webpack 5+, Vite, esbuild, Rollup).
  • Styled engine: Emotion adds ~11KB gzipped to the bundle. Pigment CSS eliminates this at build time.
  • Locale files: Each locale is a separate module. Import only the locale you need.

Theme Memoization

MUI uses unstable_memoTheme() internally to memoize style functions on theme identity. When the theme object reference doesn't change, styled components skip recalculating their styles. Avoid creating new theme objects on every render:

// BAD — new theme object every render
function App() {
  return <ThemeProvider theme={createTheme()}><Child /></ThemeProvider>;
}

// GOOD — stable theme reference
const theme = createTheme();
function App() {
  return <ThemeProvider theme={theme}><Child /></ThemeProvider>;
}

Autocomplete Performance

The Autocomplete component can degrade with very large option sets (~1M items, GitHub issue #33487). Mitigations:

  • Implement virtualized rendering via slots.listbox with a library like react-window or @tanstack/react-virtual
  • Use server-side filtering to limit the visible option count
  • Avoid re-creating the options array on every render (use useMemo)

7. Security

Supply Chain

  • All dependencies pinned via pnpm-lock.yaml
  • Resolution overrides enforce specific versions for critical packages:
    • @babel/core: 7.29.0, @babel/runtime: ^7.29.2
    • @pigment-css/*: 0.0.30
    • @types/node: 20.19.37
    • caniuse-lite: ^1.0.30001784

Third-Party Content

  • Icons sourced from Google Material Design Icons. Third-party license info for Google Material Icons is not machine-detectable (GitHub issue #47699, open). Manual license review recommended for compliance-sensitive deployments.

XSS Considerations

  • MUI components render user-provided content via React's JSX, which escapes by default
  • The dangerouslySetInnerHTML pattern is not used in MUI components
  • SVG icons use inline path data (no external resource loading)
  • The component prop allows arbitrary element types — ensure user input is not passed directly to it

Client-Side Only

MUI is a client-side UI library. It does not:

  • Make network requests (no API endpoints — 0 detected by AST extraction)
  • Store data persistently
  • Handle authentication or authorization
  • Process server-side input

Warning

When using MUI's Link component or component prop with user-provided URLs, validate the URL scheme to prevent javascript: protocol injection.


8. Developer Internals

Repository Structure

mui/material-ui/
├── packages/                    # Publishable npm packages
│   ├── mui-material/           # @mui/material — 86 components
│   ├── mui-system/             # @mui/system — theming, sx, styled()
│   ├── mui-utils/              # @mui/utils — shared utilities
│   ├── mui-lab/                # @mui/lab — incubator components
│   ├── mui-icons-material/     # @mui/icons-material — 2100+ icons
│   ├── mui-styled-engine/      # @mui/styled-engine — Emotion adapter
│   ├── mui-styled-engine-sc/   # @mui/styled-engine-sc — styled-components adapter
│   ├── mui-types/              # @mui/types — TypeScript utilities
│   ├── mui-private-theming/    # @mui/private-theming — base theme context
│   ├── mui-codemod/            # @mui/codemod — migration transforms
│   ├── mui-material-nextjs/    # @mui/material-nextjs — Next.js SSR
│   ├── mui-material-pigment-css/ # @mui/material-pigment-css
│   ├── mui-envinfo/            # @mui/envinfo — diagnostics CLI
│   ├── mui-core-downloads-tracker/ # Download counter
│   ├── mui-stylis-plugin-rtl/  # RTL styling plugin
│   └── pigment-css-react/      # Pigment CSS React bindings
├── packages-internal/           # Non-published internal packages
│   ├── api-docs-builder/       # API reference page generator
│   ├── api-docs-builder-core/  # Core builder utilities
│   ├── core-docs/              # Shared docs components (Demo, API pages)
│   ├── docs-utils/             # Docs helper utilities
│   ├── markdown/               # Markdown processing
│   ├── scripts/                # typescript-to-proptypes, generate-llms-txt
│   ├── test-utils/             # Test infrastructure
│   └── waterfall/              # Waterfall utility
├── docs/                        # Documentation site (Next.js)
│   ├── pages/                  # Next.js page routes
│   ├── data/                   # Documentation content
│   ├── src/                    # Docs site components
│   ├── translations/           # i18n files
│   └── public/                 # Static assets
├── examples/                    # 13+ framework starter projects
├── test/                        # Integration, e2e, regression, bundling tests
├── scripts/                     # Build scripts (API docs, LLM docs)
├── netlify/                     # Netlify functions and edge functions
└── patches/                     # Patch files for dependencies

Core Architectural Patterns

1. Slot Architecture

Every component follows the slots/slotProps pattern for deep customization. Internally, this is implemented via the useSlot() hook in packages/mui-material/src/utils/useSlot.ts:

function useSlot(name, parameters) {
  // name: slot name (e.g., 'root', 'input', 'listbox')
  // parameters: { elementType, ownerState, externalForwardedProps, ... }
  // Returns: [ResolvedElementType, mergedProps]
}

Merge behavior in mergeSlotProps():

  • className — merged via clsx()
  • style — shallow-merged (external wins on conflict)
  • sx — concatenated into an array
  • Event handlers (on[A-Z]*) — auto-composed (both internal and external handlers fire)
  • Non-event functions from external props — replace defaults
  • All other props — external wins

2. Polymorphic Component Pattern

The component prop is typed via OverridableComponent<TypeMap> from @mui/types:

interface ButtonTypeMap {
  props: ButtonOwnProps;
  defaultComponent: 'button';
}

declare const Button: OverridableComponent<ButtonTypeMap>;

This ensures props adjust based on the resolved element type (e.g., component={Link} adds to prop).

3. Variant-Based Styling

Components define conditional styles via variants arrays in their styled definitions:

const ButtonRoot = styled('button')({
  // base styles
  variants: [
    {
      props: { variant: 'contained', color: 'primary' },
      style: { backgroundColor: 'var(--palette-primary-main)' },
    },
    {
      props: (ownerState) => ownerState.disabled,
      style: { opacity: 0.5 },
    },
  ],
});

This replaces the older pattern of conditional CSS based on ownerState checks.

4. DefaultPropsProvider (Two-Tier Resolution)

Default props are resolved through a React context chain:

  1. System level (@mui/system/DefaultPropsProvider): getThemeProps() resolves from theme.components[name], supporting both v5 ({ defaultProps: {...} }) and v6 (flat config) signatures.
  2. Material level (@mui/material/DefaultPropsProvider): Thin wrapper with Material UI type safety (ComponentsPropsList).

5. FormControl Integration

Input components (TextField, Select, Checkbox, Switch, Radio) read state from the nearest FormControl context:

  • disabled — from FormControl or local prop (local wins)
  • error — from FormControl or local prop
  • required — from FormControl or local prop
  • focused — managed by FormControl with onFocus/onBlur forwarding

The internal SwitchBase component (shared by Checkbox, Switch, Radio) implements controlled/uncontrolled checked state, ripple, and the slots/slotProps pattern with root and input slots.

6. CSS Class Generation

Classes are generated via composeClasses() + generateUtilityClass():

// generateUtilityClass('MuiButton', 'root') → 'MuiButton-root'
// Global states: 'Mui-disabled', 'Mui-focused', 'Mui-error', etc.

The ClassNameGenerator allows customizing the prefix (e.g., for micro-frontend isolation).

Styled Engine Adapter Layer

@mui/styled-engine provides a uniform API over the actual CSS-in-JS library:

API Emotion Implementation styled-components Implementation
styled(tag) @emotion/styled styled-components (with .attrs stripped)
ThemeContext @emotion/react context styled-components theme context
keyframes @emotion/react styled-components
css @emotion/react styled-components
GlobalStyles Emotion <Global> wrapper SC createGlobalStyle wrapper
internal_mutateStyles Modifies __emotion_styles Modifies componentStyle.rules
internal_serializeStyles @emotion/serialize Passthrough
shouldForwardProp Filters MUI system props Same filter

The Interpolation<Props> type includes a variants array where each variant has props (partial match or predicate) and style (CSSObject or theme function).

Internal Tooling

TypeScript-to-PropTypes Converter

packages-internal/scripts/typescript-to-proptypes/src/ (7 files, 59,851 chars) extracts TypeScript type definitions and generates runtime PropTypes for development-mode validation. Uses the TypeScript compiler API for type resolution.

Known errors:

  • Error: No types found — when a component file has no exportable types
  • Error: Program doesn't have source files — when TS program initialization fails

API Docs Builder

packages-internal/api-docs-builder/ (29 files, 104,575 chars combined) auto-generates the 286 API reference pages in docs/pages/material-ui/api/. Uses react-docgen + Babel AST traversal to extract JSDoc, props, and slots from component source. The HookApiBuilder variant handles hooks specifically, extracting parameters and return values.

Known errors:

  • Error: The prop description... — malformed JSDoc in component source
  • TypeError: resolveType for... — unresolved TypeScript type
  • Error: Could not load a babel config — missing Babel configuration
  • Error: Impossible to resolve export specifier — circular or missing re-exports

LLM Docs Builder

scripts/buildLlmsDocs/index.ts (21,491 chars) generates LLM-friendly documentation. CLI options: --grep (filter), --outputDir, --projectSettings (required).

Known errors:

  • Error: --projectSettings is required — missing required CLI argument
  • Error: Failed to load project settings from ${path} — invalid settings file

Feature Toggles (Docs Site)

// packages-internal/core-docs/src/constants/featureToggle.ts
enable_website_banner: true
enable_docsnav_banner: true
enable_job_banner: false

Code Conventions

Convention Pattern
Component exports Default export + named type re-exports + *Classes object
CSS classes Mui{ComponentName}-{slot} (e.g., MuiButton-root)
Global states Mui-disabled, Mui-focused, Mui-error, Mui-selected, Mui-checked
Internal APIs Prefixed with unstable_ (e.g., unstable_composeClasses)
Component naming PascalCase, matches Material Design component name
Prop types TypeScript interfaces with {Component}Props naming
Theme keys camelCase matching component name without Mui prefix
Deprecated exports Re-exported with console warning, pointing to new package

Testing Strategy

  • Unit tests: Every component has tests using @testing-library/react assertions
  • Visual regression: Playwright screenshots compared pixel-by-pixel in test/regressions/screenshots/chrome/
  • Bundle validation: Each bundler fixture imports every component and validates ReactIs.isValidElementType()
  • Module resolution: Tests both CJS require() and ESM import paths resolve correctly
  • Multi-React: CI tests against React 17 and React next/experimental via pnpm use-react-version
  • Cross-browser: Chromium (default) + Firefox + WebKit via VITEST_BROWSERS

Known Issues

Issue Component Status Impact
#40843 Autocomplete Open Options DOM present when empty in freeSolo
#40250 Autocomplete Open Scroll resets when appending options
#48177 Autocomplete Open Highlight sync issue in multiple mode
#40184 Autocomplete Open Highlighted index not reset on same-length option change
#29345 All Open Material Design 3 adoption (feature request)
#33487 Autocomplete Open Performance with ~1M items
#19886 Select Open NVDA doesn't announce helper text
#42622 Dialog Open ChromeVox navigation into Dialog
#30468 ListSubheader Open Dark-mode Paper background mismatch
#48269 Codemod Open v9 codemod + unplugin-auto-import incompatibility
#18450 Autocomplete Open Pagination support for async
#38714 Autocomplete Open Virtualization / infinite scroll
#47699 Icons Open Third-party license machine-detectability

Potential Improvements

  1. Autocomplete reliability — The Autocomplete component has the highest bug density (7 of 10 reported bugs). Highlight management and scroll behavior are recurring themes.
  2. Accessibility gaps — Select + NVDA (#19886) and Dialog + ChromeVox (#42622) need aria-describedby and navigation fixes.
  3. Material Design 3 — The most-requested feature (#29345). Would require palette, typography, and shape system changes.
  4. Zero-runtime CSS — Pigment CSS integration is at v0.0.30. Stabilizing this would eliminate the Emotion runtime dependency.
  5. TypeScript strictness — exactOptionalPropertyTypes edge cases (#42694) need type-level fixes.

Contributing

The repository uses:

  • pnpm for package management (npm/yarn unsupported)
  • Prettier + ESLint + Stylelint + markdownlint + Vale for code quality
  • Conventional commits not enforced, but PRs should describe the change clearly
  • CircleCI for primary CI, GitHub Actions for publish
  • Crowdin for documentation translations

Development flow:

  1. Fork and clone
  2. pnpm install
  3. Create a branch
  4. Make changes with tests
  5. pnpm test:unit (ensure passing)
  6. pnpm prettier + pnpm eslint (ensure clean)
  7. Open PR against master branch

9. Integration Points

Styling Engine (Swappable)

MUI's styled engine is abstracted behind @mui/styled-engine. The default is Emotion; styled-components is the alternative. The engine provides:

  • styled(component)(styles) — enhanced styled function with variant support
  • ThemeContext — React context for theme
  • keyframes / css — CSS-in-JS primitives
  • GlobalStyles — global CSS injection
  • StyledEngineProvider — controls style injection order
  • internal_mutateStyles / internal_serializeStyles — internal hooks for the system layer

Switching engines requires only a bundler alias change — no source code modifications.

RTL Support

@mui/stylis-plugin-rtl provides automatic RTL style flipping. Uses the Stylis plugin API to transform CSS at injection time. Integrated via the Emotion cache:

import rtlPlugin from '@mui/stylis-plugin-rtl';
import createCache from '@emotion/cache';

const cacheRtl = createCache({ key: 'muirtl', stylisPlugins: [rtlPlugin] });

The system layer also provides RtlProvider context for component-level direction control.

Color Manipulation

@mui/system exports color utilities via colorManipulator:

  • lighten(color, coefficient) — lighten a color
  • darken(color, coefficient) — darken a color
  • alpha(color, value) — set alpha channel
  • getContrastRatio(foreground, background) — WCAG contrast ratio
  • emphasize(color, coefficient) — lighten dark colors, darken light colors

CSS Variables

The experimental CssVarsProvider enables CSS custom property-based theming:

  • unstable_createCssVarsProvider — factory for CSS vars providers
  • unstable_prepareCssVars — converts theme tokens to CSS variables
  • unstable_cssVarsParser — parses CSS variable references
  • Enables runtime mode switching (light/dark) without JavaScript theme recalculation

Container Queries

cssContainerQueries from @mui/system adds container query support to the theme, enabling responsive styles based on parent container size rather than viewport.