MUI Monorepo Architecture: A Complete Guide to the Material-UI Package Structure

The MUI monorepo architecture organizes all Material-UI runtime packages, development tools, and documentation into a single Yarn Berry workspace repository, enabling coordinated releases and shared TypeScript tooling across @mui/material, @mui/system, and @mui/base.

The mui/material-ui repository on GitHub implements a sophisticated monorepo architecture that houses the entire MUI ecosystem. This unified structure allows the team to manage multiple npm packages—from low-level unstyled primitives to high-level data grids—within a single codebase, ensuring consistent versioning and shared development infrastructure.

High-Level Directory Structure

The MUI monorepo follows a standard workspace layout where publishable code, documentation, and tooling reside at specific top-level paths:


/
├─ packages/                # All publishable npm packages

│   ├─ mui-base/           # Low-level, unstyled components & hooks

│   ├─ mui-material/       # The core component library (styled)

│   ├─ mui-system/         # Styling engine (styled, sx, theme utils)

│   ├─ mui-icons-material/ # Material Design SVG icons as React components

│   ├─ mui-lab/            # Experimental components (pre-release)

│   ├─ mui-x-data-grid/    # Advanced data-grid component

│   ├─ mui-x-date-pickers/ # Date & time pickers

│   ├─ mui-utils/          # Shared utility helpers

│   └─ mui-types/          # Shared TypeScript types

├─ docs/                    # Documentation website source

├─ examples/                # Live demo applications

├─ scripts/                 # Build, lint, and release scripts

├─ .github/                 # CI/CD configuration & issue templates

├─ .yarn/ / .yarnrc.yml     # Yarn Berry workspace configuration

├─ package.json             # Workspace root, defines workspaces & dev deps

└─ lerna.json (optional)   # Historical Lerna config for publishing

Workspace Configuration and Package Management

The MUI monorepo architecture relies on Yarn Berry (v3+) workspaces defined in the root package.json. This configuration enables deterministic dependency resolution and Plug'n'Play (PnP) support.

Each folder under packages/ represents a discrete npm package that receives independent versioning during release cycles. Shared development dependencies—including TypeScript, ESLint, and testing utilities—are hoisted to the root node_modules, eliminating duplication across workspaces.

The root package.json explicitly declares workspace globs:

{
  "workspaces": [
    "packages/*"
  ]
}

Reference: [root package.json](https://github.com/mui/material-ui/blob/master/package.json)

Core Package Architecture and Dependencies

The MUI monorepo implements a layered dependency model where foundational packages provide primitives, and higher-level packages consume them to deliver styled components.

Package Purpose Depends on Key Entry Point
@mui/base Unstyled building blocks, low-level hooks – packages/base/src/index.ts
@mui/system Styling utilities (styled, sx, ThemeProvider) @mui/base, @mui/utils packages/system/src/index.ts
@mui/material Full-featured, styled components (Button, Dialog, etc.) @mui/system, @mui/base, @mui/utils packages/material/src/index.ts
@mui/icons-material SVG icons as React components @mui/material (peer) packages/icons-material/src/index.ts
@mui/lab Experimental components that may graduate to material @mui/material, @mui/system packages/lab/src/index.ts
@mui/x-data-grid, @mui/x-date-pickers High-end components (grid, pickers) @mui/material, @mui/system respective src/index.ts files
@mui/utils Helpers (deepClone, ownerDocument, etc.) – packages/utils/src/index.ts
@mui/types Shared TypeScript types used across packages – packages/types/src/index.ts

These inter-package dependencies are declared in each package's package.json. For example, the material package's peerDependencies include @mui/system and @mui/base:

packages/material/package.json

Build Pipeline and Distribution

The MUI monorepo architecture employs a centralized build system that compiles TypeScript source into distributable formats for each package.

  1. TypeScript compilation – Each package compiles to both ESM (.js) and CommonJS (.cjs) outputs under dist/.
  2. Rollup bundles the source for distribution, generating minified builds for production.
  3. Storybook (in examples/) validates component rendering across environments.
  4. CI (GitHub Actions) runs lint, type-checking, unit tests (jest), and visual regression tests before a release.

Key script: scripts/build.js

Theming and Styling Flow

The MUI monorepo architecture separates styling concerns across @mui/system and @mui/material to provide both flexibility and convention.

  • The theme object is defined in @mui/material and extended via @mui/system's createTheme.
  • The styled engine (@mui/system/styled) uses Emotion (default) or styled-components as a pluggable backend.
  • Components consume the theme through React context (ThemeProvider).

Source: packages/system/src/createTheme.tsx

Extending the theme with a custom palette

import { createTheme, ThemeProvider } from '@mui/material/styles';
import { CssBaseline, Typography } from '@mui/material';

const theme = createTheme({
  palette: {
    primary: {
      main: '#00695c',
    },
    secondary: {
      main: '#ff6f00',
    },
  },
});

export default function App() {
  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />
      <Typography variant="h4" color="primary">
        Custom Theme Demo
      </Typography>
    </ThemeProvider>
  );
}

Relevant source: theme creation – packages/material/src/styles/createTheme.ts

Documentation and Examples Structure

The MUI monorepo architecture co-locates documentation and example applications with the source code to ensure consistency.

  • Docs are a Next.js site located under docs/. Markdown files import components directly from the monorepo, ensuring that the docs always reflect the latest code.
  • Example apps (examples/) showcase usage patterns and serve as integration tests.

Docs entry: docs/pages/getting-started/installation.md

Using experimental Lab components

The packages/mui-lab/ directory contains components that are not yet stable but available for testing.

import * as React from 'react';
import { LoadingButton } from '@mui/lab';
import SaveIcon from '@mui/icons-material/Save';

export default function SaveButton() {
  const [loading, setLoading] = React.useState(false);

  const handleClick = () => {
    setLoading(true);
    // Simulate async action
    setTimeout(() => setLoading(false), 2000);
  };

  return (
    <LoadingButton
      loading={loading}
      loadingPosition="start"
      startIcon={<SaveIcon />}
      variant="contained"
      onClick={handleClick}
    >
      Save
    </LoadingButton>
  );
}

Relevant source: Lab components – packages/lab/src/LoadingButton/LoadingButton.tsx

Summary

  • The MUI monorepo architecture consolidates all packages, documentation, and tooling under the mui/material-ui repository using Yarn Berry workspaces.
  • Layered package dependencies create a stable foundation: @mui/base provides unstyled primitives, @mui/system handles styling utilities, and @mui/material delivers fully styled components.
  • The build pipeline in scripts/build.js compiles TypeScript to both ESM and CommonJS formats, ensuring broad compatibility across bundlers.
  • Co-located documentation in docs/ and example applications in examples/ guarantee that guides and sample code remain synchronized with the latest API changes.

Frequently Asked Questions

What is the difference between @mui/base and @mui/material?

@mui/base provides unstyled, accessible component primitives and low-level hooks without any default styling, allowing complete visual customization. @mui/material builds upon @mui/base and @mui/system to offer fully styled components that implement Google's Material Design specification, including default themes and CSS.

How does the MUI monorepo handle package versioning?

The MUI monorepo architecture uses independent versioning for each package under packages/, coordinated through Yarn Berry workspaces and release scripts. While packages like @mui/material and @mui/system often release together to maintain compatibility, experimental packages in @mui/lab or premium X-series components follow separate release cadences defined in their respective package.json files.

What build outputs does the MUI monorepo generate?

Each package in the MUI monorepo compiles TypeScript source into multiple distribution formats: ES modules (.js) for modern bundlers, CommonJS (.cjs) for Node.js compatibility, and TypeScript declarations (.d.ts). The scripts/build.js orchestrator uses Rollup to generate these outputs and places them in each package's dist/ directory before publishing to npm.

Where are experimental MUI components located?

Experimental components that have not yet reached stable API status reside in the packages/mui-lab/ directory and publish to the @mui/lab npm package. These components, such as LoadingButton or the legacy Autocomplete before its stable release, import from @mui/material and @mui/system but remain separate to allow API iteration without breaking changes in the core library.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →