DEV Community

Alex Spinov
Alex Spinov

Posted on

Mantine Has a Free React Component Library With 100+ Hooks and Components

shadcn/ui is popular but copy-paste only. Chakra UI is aging. Mantine gives you 100+ components, 60+ hooks, and a complete design system — all free, all maintained, all TypeScript-first.

What Makes Mantine Different

  • 100+ components — from Button to RichTextEditor to DatePicker
  • 60+ hooks — useForm, useClipboard, useIntersection, useHotkeys
  • CSS-in-JS optional — works with any styling solution
  • Dark mode — built-in, one prop to toggle
  • Responsive — every component handles mobile

Setup

npm install @mantine/core @mantine/hooks
Enter fullscreen mode Exit fullscreen mode
import { MantineProvider, Button } from "@mantine/core";
import "@mantine/core/styles.css";

function App() {
  return (
    <MantineProvider>
      <Button variant="filled" color="blue">Click me</Button>
    </MantineProvider>
  );
}
Enter fullscreen mode Exit fullscreen mode

Components Showcase

Forms

import { useForm } from "@mantine/form";
import { TextInput, NumberInput, Select, Button } from "@mantine/core";

function RegisterForm() {
  const form = useForm({
    initialValues: { name: "", email: "", age: 18, role: "" },
    validate: {
      name: (v) => v.length < 2 ? "Name too short" : null,
      email: (v) => /^\S+@\S+$/.test(v) ? null : "Invalid email",
      age: (v) => v < 18 ? "Must be 18+" : null,
    },
  });

  return (
    <form onSubmit={form.onSubmit(console.log)}>
      <TextInput label="Name" {...form.getInputProps("name")} />
      <TextInput label="Email" {...form.getInputProps("email")} />
      <NumberInput label="Age" {...form.getInputProps("age")} />
      <Select label="Role" data={["Developer", "Designer", "Manager"]} {...form.getInputProps("role")} />
      <Button type="submit">Register</Button>
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

Data Table

import { Table, Badge, ActionIcon, Group } from "@mantine/core";

function UsersTable({ users }) {
  return (
    <Table striped highlightOnHover>
      <Table.Thead>
        <Table.Tr>
          <Table.Th>Name</Table.Th>
          <Table.Th>Role</Table.Th>
          <Table.Th>Status</Table.Th>
        </Table.Tr>
      </Table.Thead>
      <Table.Tbody>
        {users.map(user => (
          <Table.Tr key={user.id}>
            <Table.Td>{user.name}</Table.Td>
            <Table.Td>{user.role}</Table.Td>
            <Table.Td>
              <Badge color={user.active ? "green" : "gray"}>
                {user.active ? "Active" : "Inactive"}
              </Badge>
            </Table.Td>
          </Table.Tr>
        ))}
      </Table.Tbody>
    </Table>
  );
}
Enter fullscreen mode Exit fullscreen mode

Notifications

import { notifications } from "@mantine/notifications";

notifications.show({
  title: "Order placed!",
  message: "Your order #1234 has been confirmed",
  color: "green",
  autoClose: 5000,
});
Enter fullscreen mode Exit fullscreen mode

60+ Hooks

import { useClipboard, useHotkeys, useMediaQuery, useIntersection, useLocalStorage } from "@mantine/hooks";

// Copy to clipboard
const clipboard = useClipboard({ timeout: 2000 });
clipboard.copy("Hello!");

// Keyboard shortcuts
useHotkeys([
  ["mod+S", () => saveDocument()],
  ["mod+K", () => openSearch()],
]);

// Responsive
const isMobile = useMediaQuery("(max-width: 768px)");

// Intersection observer
const { ref, entry } = useIntersection({ threshold: 0.5 });

// Local storage with type safety
const [theme, setTheme] = useLocalStorage({ key: "theme", defaultValue: "dark" });
Enter fullscreen mode Exit fullscreen mode

Mantine vs Others

Mantine shadcn/ui Chakra UI MUI
Components 100+ 40+ 60+ 80+
Hooks 60+ 0 0 0
Form library Built-in No No No
Bundle approach npm package Copy-paste npm npm
TypeScript Native Native Good Good
Theming Excellent Tailwind Props ThemeProvider

Building React applications? I create web tools and data solutions. Email spinov001@gmail.com or explore my Apify tools.

Top comments (0)