---
name: using-base-ui-with-material-ui
description: Always use this skill when integrating Base UI components `@base-ui-components/react` with Material UI `@mui/material`.
---
**Announce on start**: You must announce "Using Base UI with Material UI skill" when this skill is invoked.
Always have enough context from the [Base UI documentation](https://base-ui.com/llms.txt) to build the component requested by the user.
## Base UI as the foundation
Render Base UI components as a foundation for the UI and then pass `render` prop using **proper** Material UI components.
For example, a Navigation Menu, should use `Link` from Material UI as the render element for `NavigationMenu.Link`.:
```tsx
import { NavigationMenu } from "@base-ui-components/react/navigation-menu";
import Box from "@mui/material/Box";
import Link from "@mui/material/Link";
import Typography from "@mui/material/Typography";
function MenuLink({
icon,
title,
description,
...props
}: NavigationMenu.Link.Props & {
icon?: React.ReactNode;
title: string;
description: string;
}) {
return (
}
>
{icon}
{title}
{description}
);
}
```
For full example, see [nav-menu-01.tsx](registry/blocks/nav-menu-01/nav-menu-01.tsx)
Another example, using `Button` from Material UI as the render element for Base UI `Trigger` component:
```tsx
import { Menu } from "@base-ui-components/react/menu";
import Button from "@mui/material/Button";
}>File;
```
## Styling
To style Base UI components, use `` as a render element and pass `sx` prop to it.
Always keep in mind that the sx values should be minimum since Material UI components already have default styling.
```tsx
import { NavigationMenu } from "@base-ui-components/react/navigation-menu";
import Box from "@mui/material/Box";
}
>;
```
## Primitive/Non-interactive Components
For non-interactive Base UI components like Meter, Progress, Slider (read-only), etc. that don't have direct semantic Material UI equivalents, **always use the `render` prop pattern with `Box`**.
**CRITICAL:** Never use `component={BaseUIComponent}` - this is incorrect and causes issues. Always use Base UI components as the foundation with the `render` prop.
### ✅ Correct Pattern
```tsx
import { Meter } from "@base-ui-components/react/meter";
import Box from "@mui/material/Box";
}
>
}
/>
;
```
### ❌ Incorrect Pattern
```tsx
// ❌ NEVER do this - Base UI should be the foundation, not MUI Box
// ❌ NEVER do this - Using asChild prop (not a React pattern)
```
### Key Points
1. **Base UI First**: Always render Base UI components as the outer wrapper
2. **render Prop**: Use `render={}` to apply Material UI styling
3. **Theme Tokens**: Use MUI theme tokens in sx prop (e.g., `bgcolor: "action.hover"`, `color: "text.primary"`)
4. **Minimal Styling**: Keep sx props minimal - only add what's necessary for the design
## Reduce duplication
If the same styles are used multiple times for the same Base UI components, create wrapper components to reduce duplication.
```tsx
import { NavigationMenu } from "@base-ui-components/react/navigation-menu";
function Content(props: BoxProps) {
return (
);
}
}>
}>
}>
;
```
## TypeScript Props Interface
**CRITICAL:** When creating wrapper components around Base UI primitives, NEVER duplicate props that are already provided by the Base UI component.
### ❌ Incorrect - Duplicating Base UI Props
```tsx
import { PreviewCard } from "@base-ui-components/react/preview-card";
// ❌ BAD: Manually duplicating delay, closeDelay, defaultOpen, etc.
export interface CardPreview01Props {
trigger: React.ReactNode;
href: string;
delay?: number; // Already in PreviewCard.Root.Props
closeDelay?: number; // Already in PreviewCard.Root.Props
defaultOpen?: boolean; // Already in PreviewCard.Root.Props
open?: boolean; // Already in PreviewCard.Root.Props
onOpenChange?: (open: boolean) => void; // Already in PreviewCard.Root.Props
}
```
### ✅ Correct - Extending Base UI Props
```tsx
import { PreviewCard } from "@base-ui-components/react/preview-card";
// ✅ GOOD: Extend the Base UI component props
export interface CardPreview01Props extends PreviewCard.Root.Props {
trigger: React.ReactNode;
href: string;
imageSrc: string;
imageAlt: string;
heading: string;
description: string;
}
export function CardPreview01({
trigger,
href,
imageSrc,
imageAlt,
heading,
description,
...props // This spreads all Base UI props (delay, closeDelay, defaultOpen, etc.)
}: CardPreview01Props) {
return (
{/* component content */}
);
}
```
### Key Benefits
1. **Type Safety**: Automatically get all Base UI prop types without manual maintenance
2. **Future-Proof**: New Base UI props automatically available in your component
3. **No Duplication**: Single source of truth for prop definitions
4. **Better DX**: TypeScript autocomplete shows all available props
### When to Define Custom Props
Only define props that are:
- Specific to your wrapper component (like `imageSrc`, `heading`)
- Not part of the underlying Base UI component
- Required for your custom implementation logic