All GuidesLast updated: April 2026
Migration Guide

Chakra UI to Mantine Migration Guide — Component-by-Component

Last updated: April 2026 · 12 min read

Why Switch from Chakra UI to Mantine?

Chakra UI and Mantine are both beloved React component libraries that prioritize developer experience, but Mantine has rapidly evolved into a more feature-complete ecosystem that many teams are now choosing for new projects and migrations alike. Understanding the differences helps you decide whether a migration is worth the effort for your team.

120+ hooks and utilities. Mantine ships an enormous collection of hooks through its @mantine/hooks package. From useDisclosure and useClipboard to useIntersection and useHotkeys, these hooks cover use cases that would otherwise require third-party packages. Chakra provides fewer built-in hooks, meaning your project accumulates more dependencies over time.

Superior TypeScript developer experience. While Chakra UI offers decent TypeScript support, Mantine was built TypeScript-first from day one. Every component, every prop, and every hook is fully typed with strict generic inference. Auto-completion is more reliable, prop errors are caught earlier, and the overall DX feels significantly more polished when working in VSCode or any TypeScript-aware editor.

More components out of the box.Mantine offers over 100 components compared to Chakra’s roughly 60. This includes complex widgets like DatePicker, RichTextEditor, Spotlight (command palette), Carousel, and Notifications that Chakra does not include. Having these as first-party components means consistent theming, better integration, and fewer compatibility headaches.

CSS Modules over CSS-in-JS. Starting with v7, Mantine moved away from Emotion-based CSS-in-JS to native CSS Modules and PostCSS. This eliminates runtime style injection, improves server-side rendering performance, and produces smaller bundles. Chakra UI still relies on Emotion at runtime, which can cause hydration mismatches and performance overhead in SSR-heavy applications.

Component Mapping: Chakra UI to Mantine

Below is a detailed mapping of the most commonly used Chakra UI components and their Mantine equivalents. Each example shows the Chakra source code on the left and the corresponding Mantine code on the right. You can also use the FrontFamily Converter to automate these transformations instantly.

Button

Chakra UI
<Button colorScheme="blue" variant="solid">
  Save Changes
</Button>
Mantine
<Button color="blue" variant="filled">
  Save Changes
</Button>

Input → TextInput

Chakra UI
<FormControl>
  <FormLabel>Email</FormLabel>
  <Input variant="outline" />
  <FormHelperText>Enter email</FormHelperText>
</FormControl>
Mantine
<TextInput
  label="Email"
  description="Enter email"
  variant="default"
/>

Modal

Chakra UI
<Modal isOpen={isOpen} onClose={onClose}>
  <ModalOverlay />
  <ModalContent>
    <ModalHeader>Confirm</ModalHeader>
    <ModalBody>Are you sure?</ModalBody>
    <ModalFooter>
      <Button onClick={onClose}>Cancel</Button>
    </ModalFooter>
  </ModalContent>
</Modal>
Mantine
<Modal opened={opened} onClose={close}
  title="Confirm">
  <Text>Are you sure?</Text>
  <Group mt="md" justify="flex-end">
    <Button onClick={close}>Cancel</Button>
  </Group>
</Modal>

Switch

Chakra UI
<Switch
  isChecked={enabled}
  onChange={handleChange}
  colorScheme="green"
/>
Mantine
<Switch
  checked={enabled}
  onChange={handleChange}
  color="green"
/>

Badge

Chakra UI
<Badge colorScheme="green">Active</Badge>
<Badge variant="outline">Draft</Badge>
Mantine
<Badge color="green">Active</Badge>
<Badge variant="outline">Draft</Badge>

Avatar

Chakra UI
<Avatar src={user.avatar} name={user.name} />
<Avatar name="JD" bg="blue.500" />
Mantine
<Avatar src={user.avatar} alt={user.name} />
<Avatar color="blue">JD</Avatar>

Tabs

Chakra UI
<Tabs>
  <TabList>
    <Tab>Profile</Tab>
    <Tab>Settings</Tab>
  </TabList>
  <TabPanels>
    <TabPanel>Profile content</TabPanel>
    <TabPanel>Settings content</TabPanel>
  </TabPanels>
</Tabs>
Mantine
<Tabs defaultValue="profile">
  <Tabs.List>
    <Tabs.Tab value="profile">Profile</Tabs.Tab>
    <Tabs.Tab value="settings">Settings</Tabs.Tab>
  </Tabs.List>
  <Tabs.Panel value="profile">Profile content</Tabs.Panel>
  <Tabs.Panel value="settings">Settings content</Tabs.Panel>
</Tabs>

Select

Chakra UI
<Select placeholder="Choose role">
  <option value="admin">Admin</option>
  <option value="user">User</option>
</Select>
Mantine
<Select
  placeholder="Choose role"
  data={[
    { value: 'admin', label: 'Admin' },
    { value: 'user', label: 'User' },
  ]}
/>

Tooltip

Chakra UI
<Tooltip label="More info" placement="top">
  <IconButton icon={<InfoIcon />} />
</Tooltip>
Mantine
<Tooltip label="More info" position="top">
  <ActionIcon><IconInfoCircle /></ActionIcon>
</Tooltip>

Alert

Chakra UI
<Alert status="warning">
  <AlertIcon />
  <AlertDescription>
    Session expiring soon.
  </AlertDescription>
</Alert>
Mantine
<Alert
  color="yellow"
  title="Warning"
  icon={<IconAlertTriangle />}>
  Session expiring soon.
</Alert>

Prop Conversion Reference

Migrating from Chakra UI to Mantine involves renaming several commonly used props. Chakra uses a prefix convention (is prefix for booleans, colorScheme for color tokens) while Mantine uses more standard HTML-like prop names. Here are the most common transformations:

Chakra PropMantine EquivalentNotes
isDisableddisabledStandard HTML attribute
isLoadingloadingRemoves “is” prefix
isOpenopenedPast participle convention
colorScheme="blue"color="blue"Shorter prop name
variant="solid"variant="filled"Different naming convention
size="lg"size="lg"Same size tokens
placement="top"position="top"Tooltip/Popover positioning
mt={4}mt="md"Named tokens instead of numbers

Hook Migration: Chakra to Mantine

Both libraries provide utility hooks, but Mantine’s hook library is substantially larger. Here is how the most commonly used Chakra hooks map to their Mantine equivalents, along with hooks that are exclusive to Mantine:

useDisclosure (both libraries)

Both Chakra and Mantine provide useDisclosure for toggling boolean state. The API is nearly identical: both return an array or object with open, close, and toggle handlers. In Chakra, the return value uses isOpen; in Mantine, it uses opened. A simple find-and-replace handles this migration.

useToast → notifications.show

Chakra’s useToast hook returns a function that displays toast notifications. Mantine replaces this with the @mantine/notifications package, which uses a static notifications.show() call instead of a hook. This means you can trigger notifications from anywhere, including outside of React components and inside utility functions.

useClipboard (both libraries)

Both provide useClipboardwith similar APIs. Mantine’s version includes a built-in timeout parameter for automatically resetting the copied state, which is a common UX pattern that Chakra leaves to the developer.

Mantine-exclusive hooks

Mantine includes hooks that have no Chakra equivalent: useHotkeys for keyboard shortcuts, useIntersection for scroll-based visibility, useForm for form state management with validation, useLocalStorage for persistent state, and useDebouncedValue for input debouncing. These hooks can replace several third-party dependencies in your project.

Interactive Component Reference

Search any Chakra UI component to find its Mantine equivalent. Components marked with ⚠ have no direct replacement and require custom implementation.

27 / 27
Chakra UIMantineProps / Notes
Button
colorScheme, variant, isDisabled, isLoading, leftIcon
Button
color, variant, disabled, loading, leftSection
variant="solid" becomes variant="filled"; isDisabled becomes disabled
Input
variant, isInvalid, isDisabled, placeholder
TextInput
variant, error, disabled, placeholder, label, description
Mantine TextInput includes built-in label and description; no FormControl wrapper needed
Box
bg, p, mx, borderRadius, boxShadow
Box
bg, p, mx, style
Mantine Box supports fewer style props; use style prop or CSS Modules for complex styling
Text
fontSize, color, fontWeight, noOfLines
Text
size, c, fw, lineClamp
Prop shorthand differs: fontSize becomes size, color becomes c, fontWeight becomes fw
Modal
isOpen, onClose, size, isCentered
Modal
opened, onClose, size, centered
isOpen becomes opened; requires no Overlay or Content sub-components
Badge
colorScheme, variant, fontSize
Badge
color, variant, size
colorScheme becomes color; nearly identical API
Avatar
src, name, size, bg
Avatar
src, alt, size, color
Mantine Avatar uses children for initials instead of name prop
Switch
isChecked, onChange, colorScheme, size
Switch
checked, onChange, color, size
isChecked becomes checked; colorScheme becomes color
Alert
status, variant
Alert
color, variant, title, icon
status maps to color; Mantine Alert has built-in title and icon props
Select
placeholder, value, onChange, children
Select
placeholder, value, onChange, data
Uses data array prop instead of <option> children
Spinner
size, color, thickness
Loader
size, color, type
Mantine Loader supports multiple animation types: oval, bars, dots
Progress
value, colorScheme, hasStripe, isAnimated
Progress
value, color, striped, animated
hasStripe becomes striped; isAnimated becomes animated
Tooltip
label, placement, hasArrow
Tooltip
label, position, withArrow
placement becomes position; hasArrow becomes withArrow
Divider
orientation, variant
Divider
orientation, variant, label
Mantine Divider supports a label prop for text inside the divider
Tabs
index, onChange, variant, colorScheme
Tabs
defaultValue, onChange, variant, color
Uses Tabs.List, Tabs.Tab, Tabs.Panel with value-based identification
useDisclosure
isOpen, onOpen, onClose, onToggle
useDisclosure
opened, open, close, toggle
isOpen becomes opened; onOpen becomes open (from @mantine/hooks)
useToast
title, description, status, duration
notifications.show
title, message, color, autoClose
Static function instead of hook; from @mantine/notifications package
Drawer
isOpen, onClose, placement, size
Drawer
opened, onClose, position, size
isOpen becomes opened; placement becomes position
Menu
isOpen, onClose, placement
Menu
opened, onChange, position
Uses Menu.Target, Menu.Dropdown, Menu.Item compound components
Accordion
allowToggle, allowMultiple, defaultIndex
Accordion
defaultValue, multiple, variant
Uses Accordion.Item, Accordion.Control, Accordion.Panel sub-components
NumberInput
value, onChange, min, max, step
NumberInput
value, onChange, min, max, step
Nearly identical API; Mantine adds increment/decrement controls by default
PinInput
length, onComplete, otp
PinInput
length, onComplete, oneTimeCode
otp becomes oneTimeCode; functionally identical
Skeleton
height, width, isLoaded, startColor
Skeleton
height, width, visible, animate
isLoaded becomes visible; color customization via CSS variables
Tag
colorScheme, variant, size
Badge
color, variant, size
Chakra Tag maps to Mantine Badge; no separate Tag component in Mantine
Popover
isOpen, onClose, placement, trigger
Popover
opened, onChange, position
Uses Popover.Target and Popover.Dropdown compound components
Stat
label, number, helpText
No direct equivalentNo built-in Stat component; build with Text + Group composition or use a community package
SimpleGrid
columns, spacing, minChildWidth
SimpleGrid
cols, spacing, verticalSpacing
columns becomes cols; minChildWidth uses breakpoints object instead

What Developers Actually Hit

Based on migration reports from engineering teams. These are the problems documentation doesn’t warn you about.

⚠ useDisclosure API is similar but not identical

Both libraries have useDisclosure, but Chakra returns { isOpen, onOpen, onClose, onToggle } (an object) while Mantine returns [opened, { open, close, toggle }] (a tuple). Different shape, different property names. A simple find-and-replace on isOpen to opened misses the destructuring pattern change, causing runtime errors that TypeScript catches only if you have strict mode enabled.

⚠ Chakra’s colorScheme prop doesn’t exist in Mantine

Chakra uses colorScheme="blue" for component theming. Mantine uses color="blue" but the color name mapping is not guaranteed — while Chakra’s teal and Mantine’s teal exist in both, the actual hex values at each shade level differ. Designs that depended on exact color values will look subtly wrong after a name-only migration.

⚠ Style props generate conflicting styles during migration

Chakra’s bg, p, mx work because Chakra extends styled-system. Mantine uses bg, p, mx too (since v7) but the underlying system is different — Mantine uses CSS variables, Chakra uses Emotion runtime styles. During migration when both providers are active, both systems may generate conflicting CSS for the same property on the same element, with the winner depending on injection order.

Convert Chakra UI to Mantine instantly

Skip the manual work. Paste your Chakra UI code into the FrontFamily Converter and get production-ready Mantine output with correct imports, prop mappings, and component restructuring. A pre-loaded form example is ready for you to try.

Open Converter with Chakra → Mantine Example

Styling Migration: Style Props to CSS Modules

The biggest paradigm shift. Chakra UI is built entirely around style props: you pass bg, p, mx, and borderRadius directly to components. Mantine v7 moved away from this approach toward CSS Modules and a dedicated style prop. While Mantine still supports some style props like mt and mb on all components, complex styling should be done through CSS Modules or the styles API.

Theme token differences. Chakra uses a numeric spacing scale where 4 maps to 1rem. Mantine uses named tokens: "xs", "sm", "md", "lg", "xl". Colors also differ: blue.500 in Chakra becomes blue.5 in Mantine (0-9 scale instead of 50-900).

Server-side rendering. Because Mantine uses CSS Modules instead of runtime CSS-in-JS, SSR is dramatically simpler. There is no need for Emotion cache configuration, no risk of hydration mismatches from style injection order, and no flash of unstyled content. This makes Mantine a particularly strong choice for Next.js applications where server components are the default.

Import Changes at a Glance

Chakra UI
import { Button } from '@chakra-ui/react';
import { Input } from '@chakra-ui/react';
import { Modal, ModalOverlay } from '@chakra-ui/react';
import { useDisclosure } from '@chakra-ui/react';
import { useToast } from '@chakra-ui/react';
Mantine
import { Button } from '@mantine/core';
import { TextInput } from '@mantine/core';
import { Modal } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { notifications } from '@mantine/notifications';