Material UI (MUI) Cheat Sheet
Overview
Material UI (MUI) is the most popular React UI component library, implementing Google’s Material Design specification. It provides a comprehensive set of pre-built, production-ready components including buttons, dialogs, menus, tables, forms, and layout primitives. MUI offers deep customization through its theme system, styled API, and the sx prop for inline styling.
MUI consists of several packages: MUI Core (Material UI components), MUI Base (unstyled headless components), MUI System (CSS utilities), and MUI X (advanced data grid, date pickers, and charts). The library supports both Emotion and styled-components as CSS-in-JS engines, along with CSS variables for theme management.
Installation
# Core Material UI with Emotion (default)
npm install @mui/material @emotion/react @emotion/styled
# With styled-components instead
npm install @mui/material @mui/styled-engine-sc styled-components
# Icons
npm install @mui/icons-material
# Date pickers
npm install @mui/x-date-pickers dayjs
# Data Grid
npm install @mui/x-data-grid
# Lab (experimental components)
npm install @mui/lab
# Add Roboto font
npm install @fontsource/roboto
Setup
// main.tsx
import "@fontsource/roboto/300.css"
import "@fontsource/roboto/400.css"
import "@fontsource/roboto/500.css"
import "@fontsource/roboto/700.css"
import { ThemeProvider, createTheme, CssBaseline } from "@mui/material"
const theme = createTheme()
function App() {
return (
<ThemeProvider theme={theme}>
<CssBaseline />
{/* Your app content */}
</ThemeProvider>
)
}
Core Components
Common Components
| Component | Import | Description |
|---|---|---|
Button | @mui/material/Button | Action buttons with variants |
TextField | @mui/material/TextField | Text input fields |
Select | @mui/material/Select | Dropdown select |
Checkbox | @mui/material/Checkbox | Checkbox input |
Switch | @mui/material/Switch | Toggle switch |
Slider | @mui/material/Slider | Range slider |
Dialog | @mui/material/Dialog | Modal dialog |
Snackbar | @mui/material/Snackbar | Toast notifications |
AppBar | @mui/material/AppBar | Top app bar |
Drawer | @mui/material/Drawer | Side navigation |
Card | @mui/material/Card | Content card |
Table | @mui/material/Table | Data table |
Tabs | @mui/material/Tabs | Tab navigation |
Chip | @mui/material/Chip | Compact element |
Avatar | @mui/material/Avatar | User avatar |
Tooltip | @mui/material/Tooltip | Hover tooltip |
Skeleton | @mui/material/Skeleton | Loading placeholder |
Button Variants
import Button from "@mui/material/Button"
import IconButton from "@mui/material/IconButton"
import DeleteIcon from "@mui/icons-material/Delete"
// Variants
<Button variant="contained">Primary</Button>
<Button variant="outlined">Secondary</Button>
<Button variant="text">Text</Button>
// Colors
<Button variant="contained" color="primary">Primary</Button>
<Button variant="contained" color="secondary">Secondary</Button>
<Button variant="contained" color="error">Error</Button>
<Button variant="contained" color="success">Success</Button>
// Sizes
<Button size="small">Small</Button>
<Button size="medium">Medium</Button>
<Button size="large">Large</Button>
// With icon
<Button variant="contained" startIcon={<DeleteIcon />}>Delete</Button>
// Icon button
<IconButton color="primary" aria-label="delete">
<DeleteIcon />
</IconButton>
// Loading button (from @mui/lab)
import LoadingButton from "@mui/lab/LoadingButton"
<LoadingButton loading variant="contained">Submit</LoadingButton>
Form Components
import { TextField, Select, MenuItem, FormControl, InputLabel, Autocomplete } from "@mui/material"
// Text field variants
<TextField label="Name" variant="outlined" />
<TextField label="Email" variant="filled" />
<TextField label="Phone" variant="standard" />
// Validation
<TextField label="Email" type="email" required error={!!errors.email}
helperText={errors.email || "Enter your email"} />
// Multiline
<TextField label="Bio" multiline rows={4} />
// Select
<FormControl fullWidth>
<InputLabel>Role</InputLabel>
<Select value={role} label="Role" onChange={handleChange}>
<MenuItem value="admin">Admin</MenuItem>
<MenuItem value="user">User</MenuItem>
<MenuItem value="viewer">Viewer</MenuItem>
</Select>
</FormControl>
// Autocomplete
<Autocomplete
options={["React", "Vue", "Angular", "Svelte"]}
renderInput={(params) => <TextField {...params} label="Framework" />}
/>
Layout Components
import { Box, Stack, Grid, Container, Paper } from "@mui/material"
// Box (basic div with sx prop)
<Box sx={{ p: 2, bgcolor: "background.paper", borderRadius: 1 }}>
Content
</Box>
// Stack (flex column/row)
<Stack direction="row" spacing={2} alignItems="center">
<Button>One</Button>
<Button>Two</Button>
</Stack>
// Grid (responsive layout)
<Grid container spacing={2}>
<Grid item xs={12} md={6} lg={4}>
<Paper sx={{ p: 2 }}>Column 1</Paper>
</Grid>
<Grid item xs={12} md={6} lg={4}>
<Paper sx={{ p: 2 }}>Column 2</Paper>
</Grid>
</Grid>
Configuration
Custom Theme
import { createTheme, ThemeProvider } from "@mui/material/styles"
const theme = createTheme({
palette: {
mode: "dark", // or "light"
primary: {
main: "#1976d2",
light: "#42a5f5",
dark: "#1565c0",
},
secondary: {
main: "#9c27b0",
},
background: {
default: "#121212",
paper: "#1e1e1e",
},
},
typography: {
fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif',
h1: { fontSize: "2.5rem", fontWeight: 700 },
h2: { fontSize: "2rem", fontWeight: 600 },
button: { textTransform: "none" },
},
shape: {
borderRadius: 8,
},
components: {
MuiButton: {
defaultProps: {
disableElevation: true,
},
styleOverrides: {
root: {
borderRadius: 8,
padding: "8px 24px",
},
},
},
MuiCard: {
styleOverrides: {
root: {
borderRadius: 12,
boxShadow: "0 2px 12px rgba(0,0,0,0.08)",
},
},
},
},
})
function App() {
return (
<ThemeProvider theme={theme}>
<CssBaseline />
{/* App content */}
</ThemeProvider>
)
}
The sx Prop
// sx prop for inline theme-aware styling
<Box
sx={{
p: 2, // padding: theme.spacing(2)
m: 1, // margin: theme.spacing(1)
bgcolor: "primary.main", // theme palette color
color: "primary.contrastText",
borderRadius: 1, // theme.shape.borderRadius * 1
width: { xs: "100%", md: "50%" }, // responsive
display: "flex",
gap: 2,
"&:hover": {
bgcolor: "primary.dark",
},
}}
>
Themed box
</Box>
Advanced Usage
Data Grid (MUI X)
import { DataGrid, GridColDef } from "@mui/x-data-grid"
const columns: GridColDef[] = [
{ field: "id", headerName: "ID", width: 70 },
{ field: "name", headerName: "Name", width: 200, editable: true },
{ field: "email", headerName: "Email", width: 250 },
{ field: "role", headerName: "Role", width: 130,
type: "singleSelect",
valueOptions: ["Admin", "User", "Viewer"] },
]
const rows = [
{ id: 1, name: "Alice", email: "alice@example.com", role: "Admin" },
{ id: 2, name: "Bob", email: "bob@example.com", role: "User" },
]
<DataGrid
rows={rows}
columns={columns}
pageSize={10}
checkboxSelection
disableRowSelectionOnClick
sortingMode="server"
filterMode="server"
/>
Styled Components API
import { styled } from "@mui/material/styles"
const StyledCard = styled("div")(({ theme }) => ({
padding: theme.spacing(3),
borderRadius: theme.shape.borderRadius * 2,
backgroundColor: theme.palette.background.paper,
boxShadow: theme.shadows[4],
transition: "box-shadow 0.2s",
"&:hover": {
boxShadow: theme.shadows[8],
},
}))
<StyledCard>Custom styled content</StyledCard>
Dark Mode Toggle
import { useState, useMemo } from "react"
import { createTheme, ThemeProvider } from "@mui/material/styles"
import useMediaQuery from "@mui/material/useMediaQuery"
function App() {
const prefersDark = useMediaQuery("(prefers-color-scheme: dark)")
const [mode, setMode] = useState<"light" | "dark">(prefersDark ? "dark" : "light")
const theme = useMemo(() => createTheme({ palette: { mode } }), [mode])
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<Button onClick={() => setMode(mode === "light" ? "dark" : "light")}>
Toggle {mode === "light" ? "Dark" : "Light"} Mode
</Button>
</ThemeProvider>
)
}
Troubleshooting
| Issue | Solution |
|---|---|
| Styles not applying | Ensure ThemeProvider wraps your app; add CssBaseline |
| Flash of unstyled content | Configure SSR with Emotion cache; use @emotion/cache |
| Bundle size too large | Use path imports: import Button from '@mui/material/Button' |
| TypeScript theme errors | Extend the theme interface with declare module '@mui/material/styles' |
| Grid not responsive | Use breakpoint props: xs, sm, md, lg, xl |
| Icons not rendering | Install @mui/icons-material; verify import path |
| Emotion conflicts | Ensure only one version of @emotion/react is installed |
| sx prop not working | Component must be an MUI component or wrapped with styled() |
| Dark mode flicker on SSR | Use CSS variables mode: cssVariables: true in createTheme |