# Joy UI vs Material UI: Key Differences and When to Use Each

> Compare Joy UI and Material UI to understand their key differences, component counts, and theming approaches, helping you choose the best fit for your next React project.

- Repository: [MUI/material-ui](https://github.com/mui/material-ui)
- Tags: comparison
- Published: 2026-02-26

---

**Material UI implements Google’s Material Design specification with over 100 components and compile-time static theming, while Joy UI provides a lightweight, design-system-agnostic alternative with approximately 30 components and runtime CSS-variable theming.**

When building React applications within the MUI ecosystem, choosing between these two distinct libraries impacts your design flexibility, bundle size, and theming capabilities. Both packages share the same underlying styled engine and React-compatible APIs, yet they serve different architectural purposes within the `mui/material-ui` repository.

## Design Philosophy and Architectural Overview

### Material UI: Material Design Implementation

Material UI adheres strictly to **Google’s Material Design** specification. The components implement elevation systems, motion cues, and visual patterns defined by Material guidelines, including distinctive ripple effects and shadow hierarchies. In [`packages/mui-material/src/Button/Button.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/Button/Button.tsx), the implementation relies on Material-Design-specific CSS rules that enforce this opinionated visual language across all components.

### Joy UI: Neutral and Flexible

Joy UI introduces the **Joy design system**, a lighter, more neutral aesthetic untethered from external specifications. The architecture emphasizes simplicity, high-contrast accessibility, and flexible theming through CSS variables. As implemented in [`packages/mui-joy/src/Button/Button.tsx`](https://github.com/mui/material-ui/blob/main/packages/mui-joy/src/Button/Button.tsx), components expose richer variant props (`soft`, `outlined`, `plain`) and rely on runtime CSS variables rather than static compiled styles.

## Theme System and Configuration

### Material UI Static Theming

Material UI uses a theme object created with **`createTheme`** in [`packages/mui-material/src/styles/createTheme.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/styles/createTheme.ts). This theme contains palettes, typography, spacing, and component defaults that follow Material Design. However, the theme remains **static at compile time**; changing a palette after mount requires re-creating the theme and re-rendering the `ThemeProvider`.

### Joy UI Runtime Theming

Joy UI employs **`createJoyTheme`** from [`packages/mui-joy/src/styles/createJoyTheme.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-joy/src/styles/createJoyTheme.ts), which adds extra design tokens including `radius`, `shadow`, and **`colorSchemes`**. This architecture supports **runtime palette switching** via CSS variables, enabling smooth transitions between light and dark modes without full re-renders. The `useColorScheme` hook in [`packages/mui-joy/src/useColorScheme.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-joy/src/useColorScheme.ts) provides the API for toggling these schemes on the fly.

## Component Implementation Details

### Material UI Component Architecture

Components in `packages/mui-material/src/` are built on the styled engine (Emotion or styled-components) and bundle Material-Design-specific behaviors. The Button component includes ripple effects and elevation shadows by default, contributing to a larger baseline bundle size that requires tree-shaking to optimize.

### Joy UI Component Architecture

Joy UI components in `packages/mui-joy/src/` share the same styled engine but remain lighter and more customizable. The Button implementation exposes variants like `soft` and `plain` that use CSS variables for styling, resulting in a smaller footprint and higher customization potential without overriding complex Material-specific CSS.

## Component Catalog and Bundle Size

Material UI provides **over 100 components**, including complex data-display components like DataGrid, Pickers, TreeView, and Lab components. This comprehensive catalog comes with a larger out-of-the-box bundle size due to the full Material Design system defaults.

Joy UI offers a focused set of approximately **30 core components** covering essential UI building blocks (Button, Card, Avatar, Slider). The intentionally slimmer catalogue and reduced default styling produce a smaller baseline bundle, making it ideal for applications prioritizing performance and minimal overhead.

## When to Use Material UI

Choose Material UI when your product must maintain **strict consistency with Material Design**, such as Android applications or Google-styled dashboards. Select it when you require the **extensive component catalogue** (DataGrid, date pickers, data visualization) or when leveraging the mature ecosystem of third-party extensions and well-documented guidelines.

## When to Use Joy UI

Opt for Joy UI when you need a **design-system-agnostic** foundation that supports brand-centric customization without Material Design constraints. Use it for applications requiring **smooth runtime theming** (instant light/dark toggles) or when bundle size is critical, as Joy UI’s CSS-variable architecture and minimal defaults provide a lightweight starting point.

## Practical Code Examples

### Creating Themes

Material UI uses `createTheme` with a static palette:

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

const materialTheme = createTheme({
  palette: {
    primary: { main: '#1976d2' },
    mode: 'light',
  },
});

export default function App() {
  return (
    <ThemeProvider theme={materialTheme}>
      <CssBaseline />
      {/* … */}
    </ThemeProvider>
  );
}

```

Joy UI uses `createJoyTheme` with runtime color schemes:

```tsx
import { createJoyTheme, ThemeProvider } from '@mui/joy/styles';
import CssBaseline from '@mui/joy/CssBaseline';

const joyTheme = createJoyTheme({
  colorSchemes: {
    light: {
      palette: { primary: { solidBg: '#1976d2' } },
    },
    dark: {
      palette: { primary: { solidBg: '#90caf9' } },
    },
  },
});

export default function App() {
  return (
    <ThemeProvider theme={joyTheme}>
      <CssBaseline />
      {/* … */}
    </ThemeProvider>
  );
}

```

### Button Variants

Material UI provides Material-specific variants:

```tsx
import Button from '@mui/material/Button';

function SaveButton() {
  return (
    <Button variant="contained" color="primary">
      Save
    </Button>
  );
}

```

Joy UI offers additional flexible variants:

```tsx
import Button from '@mui/joy/Button';

function SaveButton() {
  return (
    <Button variant="soft" color="primary">
      Save
    </Button>
  );
}

```

### Runtime Color-Scheme Toggle

Joy UI enables theme switching without re-rendering:

```tsx
import { useColorScheme } from '@mui/joy';
import Button from '@mui/joy/Button';

function ThemeToggle() {
  const { mode, setMode } = useColorScheme();

  return (
    <Button onClick={() => setMode(mode === 'light' ? 'dark' : 'light')}>
      Switch to {mode === 'light' ? 'dark' : 'light'} mode
    </Button>
  );
}

```

## Summary

- **Material UI** implements strict Material Design with 100+ components, static theming via `createTheme`, and larger bundle sizes ideal for Google-centric design systems.
- **Joy UI** provides a neutral, lightweight foundation with ~30 components, runtime CSS-variable theming via `createJoyTheme`, and the `useColorScheme` hook for instant theme switching.
- Both libraries share the same styled engine and `sx` prop API, allowing imports from `@mui/material` or `@mui/joy` with minimal architectural friction.
- Choose Material UI for comprehensive component coverage and Material Design compliance; choose Joy UI for customizable, brand-agnostic interfaces with smaller bundles.

## Frequently Asked Questions

### Can I use Material UI and Joy UI components in the same project?

Yes. Both libraries share the same underlying styled engine and utility classes. You can import components from `@mui/material` and `@mui/joy` simultaneously, though you should avoid nesting `ThemeProvider` instances from both packages to prevent CSS variable conflicts. Maintain separate theme configurations for each design system.

### Is Joy UI production-ready compared to Material UI?

Joy UI is stable and production-ready, though its component catalogue (~30 components) is smaller than Material UI’s extensive offering. As implemented in the `mui/material-ui` repository, Joy UI receives the same testing and maintenance standards as Material UI, but it lacks some complex components like DataGrid that remain Material UI-specific.

### How does runtime theming work in Joy UI?

Joy UI’s `createJoyTheme` in [`packages/mui-joy/src/styles/createJoyTheme.ts`](https://github.com/mui/material-ui/blob/main/packages/mui-joy/src/styles/createJoyTheme.ts) generates CSS custom properties (variables) for design tokens like colors and radius. The `useColorScheme` hook toggles these variables on the document root, allowing instant theme changes without React re-renders. Material UI requires recreating the theme object and re-rendering the provider to achieve similar effects.

### Which package has better TypeScript support?

Both packages provide comprehensive TypeScript definitions. Material UI’s types are more mature and extensive due to its longer development history, while Joy UI’s types in `packages/mui-joy/src/` offer stricter typing for variant props like `soft` and `plain`. Both support the `sx` prop and theme augmentation patterns.