@chakra-ui/react, @emotion/react, @mui/material, and @radix-ui/themes represent different approaches to building user interfaces in React. @chakra-ui/react is a component library focused on developer speed and prop-based styling. @emotion/react is a low-level CSS-in-JS library that powers many other frameworks, offering maximum styling flexibility. @mui/material is a comprehensive enterprise-grade library implementing Google's Material Design with a vast set of pre-built components. @radix-ui/themes is a modern component library built on accessible primitives, providing a polished design system out of the box with a focus on web standards and accessibility.
Building a React application requires making a critical decision about how to handle styles and components. The four packages in this comparison — @chakra-ui/react, @emotion/react, @mui/material, and @radix-ui/themes — take very different approaches. Some provide complete sets of pre-built components, while others offer the underlying tools to build your own. Let's explore how they handle real-world engineering tasks.
How you apply styles to an element defines your daily developer experience. These libraries range from high-level prop-based styling to low-level CSS primitives.
@chakra-ui/react uses a style-props system.
// chakra: Style props
import { Box, Text } from '@chakra-ui/react';
function Card() {
return (
<Box p={4} bg="white" borderRadius="md" shadow="sm">
<Text fontWeight="bold">Hello</Text>
</Box>
);
}
@emotion/react uses the css prop or styled components.
// emotion: CSS prop
import { css } from '@emotion/react';
function Card() {
return (
<div css={css`
padding: 1rem;
background: white;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
`}>
<span style={{ fontWeight: 'bold' }}>Hello</span>
</div>
);
}
@mui/material supports both sx props and styled components.
sx prop is similar to Chakra but more powerful.// mui: SX prop
import { Box, Typography } from '@mui/material';
function Card() {
return (
<Box sx={{ p: 2, bgcolor: 'background.paper', borderRadius: 1 }}>
<Typography fontWeight="bold">Hello</Typography>
</Box>
);
}
@radix-ui/themes uses a class-based utility system via className or style props.
style prop or global CSS for custom tweaks.// radix: Component props + style
import { Box, Text } from '@radix-ui/themes';
function Card() {
return (
<Box p="4" style={{ background: 'var(--gray-1)' }}>
<Text weight="bold">Hello</Text>
</Box>
);
}
Creating a basic interactive element reveals how much opinion each library enforces.
@chakra-ui/react provides a pre-styled Button component.
// chakra: Pre-built Button
import { Button } from '@chakra-ui/react';
function Submit() {
return <Button colorScheme="blue" variant="solid">Submit</Button>;
}
@emotion/react requires you to build the Button from scratch.
// emotion: Custom Styled Button
import styled from '@emotion/styled';
const StyledButton = styled.button`
background: blue;
color: white;
padding: 8px 16px;
border: none;
&:hover { background: darkblue; }
`;
function Submit() {
return <StyledButton>Submit</StyledButton>;
}
@mui/material offers a highly configurable Button.
// mui: Material Button
import { Button } from '@mui/material';
function Submit() {
return <Button variant="contained" color="primary">Submit</Button>;
}
@radix-ui/themes provides a polished Button component.
// radix: Themes Button
import { Button } from '@radix-ui/themes';
function Submit() {
return <Button color="blue" variant="solid">Submit</Button>;
}
Handling color modes is a common requirement for modern web apps.
@chakra-ui/react has built-in dark mode support.
ColorModeScript and ChakraProvider.// chakra: Dark mode toggle
import { useColorMode, Button } from '@chakra-ui/react';
function Toggle() {
const { colorMode, toggleColorMode } = useColorMode();
return <Button onClick={toggleColorMode}>Switch to {colorMode === 'light' ? 'dark' : 'light'}</Button>;
}
@emotion/react does not have built-in theming logic.
ThemeProvider to pass variables down.// emotion: Manual Theme Context
import { ThemeProvider } from '@emotion/react';
function App() {
const theme = { bg: 'white', text: 'black' };
return <ThemeProvider theme={theme}>...</ThemeProvider>;
}
@mui/material uses a robust CssVarsProvider or ThemeProvider.
createTheme function.// mui: Theme Provider
import { ThemeProvider, createTheme } from '@mui/material/styles';
const theme = createTheme({ palette: { mode: 'dark' } });
function App() {
return <ThemeProvider theme={theme}>...</ThemeProvider>;
}
@radix-ui/themes handles themes via the Theme component.
appearance prop to control light/dark.// radix: Theme Component
import { Theme } from '@radix-ui/themes';
function App() {
return <Theme appearance="dark">...</Theme>;
}
Accessibility is not optional for professional applications.
@chakra-ui/react bakes ARIA attributes into components.
// chakra: Accessible Modal
import { Modal, ModalOverlay, ModalContent } from '@chakra-ui/react';
// Focus trap and aria-hidden managed internally
@emotion/react provides no accessibility features.
// emotion: Manual ARIA
<button aria-label="Close" onClick={handleClose}>X</button>
@mui/material follows WAI-ARIA authoring practices strictly.
// mui: Accessible Menu
import { Menu, MenuItem } from '@mui/material';
// Keyboard arrow navigation works out of the box
@radix-ui/themes is built on top of Radix Primitives.
// radix: Accessible Dialog
import { Dialog } from '@radix-ui/themes';
// Built on @radix-ui/react-dialog which handles focus trap
Despite their differences, these libraries share common goals and React patterns.
// Shared: TypeScript Props
interface ButtonProps { label: string; onClick: () => void; }
const Button = ({ label, onClick }: ButtonProps) => <button onClick={onClick}>{label}</button>;
// Shared: CSS Variable Usage
<div style={{ color: 'var(--primary-color)' }}>Text</div>
// Chakra/MUI: Responsive Array
<Box width={["100%", "50%", "25%"]} />
// Radix: Media Queries via CSS
// Emotion: Media queries in css blocks
| Feature | @chakra-ui/react | @emotion/react | @mui/material | @radix-ui/themes |
|---|---|---|---|---|
| Type | Component Library | Styling Engine | Component Library | Component Library |
| Styling | Prop-based | CSS-in-JS | SX Prop / Styled | Class / Style Props |
| Design | Customizable | None (You build) | Material Design | Modern / Clean |
| Accessibility | High | None (Manual) | Very High | Very High |
| Bundle Size | Medium | Low (Core) | Large | Medium |
@chakra-ui/react is the speed runner 🏃. It removes friction for getting UI on the screen. Use it for internal dashboards, MVPs, or when your team wants to avoid CSS debates.
@emotion/react is the foundation 🧱. It is not a UI kit but the tool to build one. Use it if you have a custom design system that doesn't fit existing libraries.
@mui/material is the enterprise tank 🛡️. It is heavy but covers every edge case. Use it for complex admin panels where you need data grids, pickers, and strict consistency.
@radix-ui/themes is the modern standard 📐. It balances pre-styled convenience with accessibility rigor. Use it for public-facing apps where performance and inclusivity are critical.
Final Thought: There is no single best choice. If you need speed, pick Chakra. If you need control, pick Emotion. If you need features, pick MUI. If you need accessibility and modern web standards, pick Radix Themes.
Choose @chakra-ui/react if you want to build internal tools or prototypes quickly without worrying about design details. It is ideal for teams that prefer styling components directly via props rather than managing separate CSS files or objects. This package works well when you need a consistent theme system that is easy to customize without deep CSS knowledge.
Choose @emotion/react if you need full control over your styles and want to build your own component system from scratch. It is best suited for projects where existing component libraries feel too restrictive or heavy. Use this when you want CSS-in-JS features like dynamic styles, server-side rendering support, and source maps without being tied to a specific UI design language.
Choose @mui/material if you are building a complex enterprise application that benefits from a strict design system like Material Design. It is the right choice when you need a massive catalog of pre-built, accessible components (like data grids or date pickers) and have the resources to handle a larger bundle size. This package excels in dashboards and admin panels where consistency and feature depth matter most.
Choose @radix-ui/themes if accessibility and modern web standards are your top priorities. It is perfect for teams that want pre-styled components without the heavy weight of older libraries. Select this when you want a clean, contemporary look that is easy to theme, while still retaining the ability to drop down to unstyled primitives for custom behavior if needed.
Works out of the box. Chakra UI contains a set of polished React components that work out of the box.
Flexible & composable. Chakra UI components are built on top of a React UI Primitive for endless composability.
Accessible. Chakra UI components follows the WAI-ARIA guidelines specifications.
Dark Mode 😍: All components are dark mode compatible.
⚡️Chakra UI is made up of multiple components and tools which you can import one
by one. All you need to do is install the @chakra-ui/react package:
$ yarn add @chakra-ui/react
# or
$ npm install --save @chakra-ui/react
To start using the components, please follow these steps:
ThemeProvider provided by @chakra-ui/reactimport { ColorModeProvider, ThemeProvider } from "@chakra-ui/react"
const App = ({ children }) => (
<ThemeProvider>
<ColorModeProvider>{children}</ColorModeProvider>
</ThemeProvider>
)
ColorModeProvider is a context that provides light mode and dark mode values
to the components. It also comes with a function to toggle between light/dark
mode.
import { Button } from "@chakra-ui/react"
const App = () => <Button>I just consumed some ⚡️Chakra!</Button>
Feel like contributing? That's awesome! We have a contributing guide to help guide you.
The components to be built come from the Aria Practices Design Patterns and Widgets.
Thanks goes to these wonderful people (emoji key):
Segun Adebayo 💻 🚧 📖 💡 🎨 | Tioluwani Kolawole 📖 💡 🚧 |
This project follows the all-contributors specification. Contributions of any kind welcome!