# Shadcn Checkbox
URL: /ui/checkbox
React checkbox component with three states and form integration. Built with TypeScript and Tailwind CSS for Next.js applications using Radix UI primitives.

Ever seen users frantically click a checkbox that doesn't respond? Or watch them struggle with terms and conditions they can't actually check? Yeah, checkboxes seem simple until they're not. This shadcn/ui checkbox actually responds when clicked and works the way users expect.

### Checkbox showcase

Three states that actually work:

<Preview path="ui/checkbox-demo" />

Built on Radix UI primitives with proper TypeScript types and ARIA attributes. Styled with Tailwind CSS so it matches your design system instead of browser defaults that look like they're from 1995.

```bash
npx shadcn@latest add checkbox
```

## Why checkboxes actually handle selections

Here's the thing—checkboxes are everywhere, but most of them suck. They're too small to hit on mobile, they don't show focus states, they break when you try to style them, or they just don't respond consistently. Users expect checkboxes to work like checkboxes, not puzzle games.

Think about the last time you tried to accept terms and conditions on mobile. Tiny checkbox, no visual feedback, you're not even sure if you clicked it. Then you submit the form and get an error because the checkbox wasn't actually checked. Frustrating for users, support tickets for you.

This free shadcn checkbox handles all the edge cases—keyboard navigation, indeterminate states, form integration—while you focus on your business logic. Whether you're building settings panels, multi-select filters, or terms acceptance in your JavaScript apps, checkboxes that work reliably keep users happy.

## Common checkbox patterns you'll actually use

### Multiple selections

Filters, bulk actions, and multi-select lists:

<Preview path="ui/checkbox-form-multiple" />

### Controlled state management

When you need programmatic control:

<Preview path="ui/checkbox-controlled" />

### Disabled states

Show unavailable options:

<Preview path="ui/checkbox-disabled" />

## Features

This free open source checkbox component includes everything you need:

- **TypeScript-first** - Full type safety with proper boolean and indeterminate states
- **Three states** - Checked, unchecked, and indeterminate for partial selections
- **Radix UI powered** - Battle-tested accessibility and keyboard navigation
- **Tailwind CSS styled** - Customize with utilities, not fighting browser defaults
- **Form integration** - Works seamlessly with React Hook Form and native forms
- **Mobile optimized** - Touch targets that actually work on phones
- **Screen reader friendly** - Proper ARIA attributes and state announcements

## API Reference

### Checkbox Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `checked` | `boolean \| "indeterminate"` | - | Controlled checked state |
| `defaultChecked` | `boolean \| "indeterminate"` | - | Default checked state |
| `onCheckedChange` | `(checked: boolean \| "indeterminate") => void` | - | Change handler |
| `disabled` | `boolean` | - | Disabled state |
| `required` | `boolean` | - | Required for form validation |
| `name` | `string` | - | Form field name |
| `value` | `string` | `"on"` | Form field value |

### States and Data Attributes

| State | Data Attribute | Use Case |
| --- | --- | --- |
| Checked | `[data-state="checked"]` | Fully selected |
| Unchecked | `[data-state="unchecked"]` | Not selected |
| Indeterminate | `[data-state="indeterminate"]` | Partial selection |
| Disabled | `[data-disabled]` | Non-interactive |

### Keyboard Navigation

| Key | Action |
| --- | --- |
| `Space` | Toggle checked state |
| `Tab` | Move focus to next element |

## Production tips

**Make touch targets bigger.** This free shadcn/ui checkbox looks good at default size, but mobile users need bigger tap areas. Wrap in a larger clickable area or increase padding. Your React checkbox should work for thumbs, not just precise mouse clicks.

**Use indeterminate for parent selections.** When building hierarchical lists, parent checkboxes should show indeterminate state when some (but not all) children are selected. This TypeScript component handles the state—you handle the logic.

**Don't rely on color alone.** The checkbox icon provides visual feedback beyond just background color changes. Color-blind users and high-contrast displays need shape changes too. Your Next.js app should be accessible to everyone.

**Immediate visual feedback.** Users expect instant response when clicking. This open source shadcn component provides smooth animations and state changes. Don't add artificial delays or loading states to simple checkbox interactions.

**Form validation that makes sense.** Required checkboxes should show clear error messages when not checked. "This field is required" beats cryptic validation text. Your JavaScript forms should guide users, not confuse them.

## Integration with other components

Checkboxes work naturally with [Form](/ui/form) components for validation and submission in your React applications. Use [Label](/ui/label) components to create larger click targets and improve accessibility.

For multi-select scenarios, combine checkboxes with [Card](/ui/card) components to group related options. This open source pattern works well for settings panels and preference screens. When building data tables, pair checkboxes with [Table](/ui/table) components for bulk selection patterns.

In filter interfaces, group checkboxes with [Separator](/ui/separator) components to organize options logically. Your JavaScript components stay organized while providing clear visual hierarchy for complex selection interfaces.

## Questions you might have

<Accordions type="single">
  <Accordion id="checkbox-vs-switch" title="When should I use Checkbox vs Switch?">
    Use checkboxes for independent yes/no choices that users confirm by submitting forms. Use switches for settings that take effect immediately. The shadcn checkbox is perfect for "I agree to terms" or multi-select lists. Switches work better for "Enable notifications" settings.
  </Accordion>

  <Accordion id="checkbox-indeterminate" title="How do I handle indeterminate states?">
    Set `checked="indeterminate"` when some child items are selected but not all. This TypeScript component manages the visual state—you manage the selection logic. Common in tree views and hierarchical lists where parent items show partial selection.
  </Accordion>

  <Accordion id="checkbox-form-integration" title="How do checkboxes work with form libraries?">
    The checkbox works with React Hook Form, Formik, and native HTML forms. Use the `name` and `value` props for form submission. The free shadcn component handles the input element internally—just manage the checked state normally.
  </Accordion>

  <Accordion id="checkbox-accessibility" title="Are checkboxes accessible by default?">
    Yes, the component uses proper ARIA attributes and semantic HTML. Screen readers announce the label, state, and required status. But accessibility depends on your implementation—always pair with descriptive labels and logical tab order in your Next.js application.
  </Accordion>

  <Accordion id="checkbox-mobile-touch" title="Do checkboxes work well on mobile?">
    The component has proper touch targets, but consider your layout. Tiny checkboxes in long lists are hard to tap accurately. Increase padding around checkboxes or make entire list items clickable. Your React app should feel natural on touch devices.
  </Accordion>

  <Accordion id="checkbox-styling" title="Can I customize the checkbox appearance?">
    Use Tailwind CSS utilities to override colors, sizes, and borders. The open source component uses CSS custom properties internally. For completely custom styling, the data attributes let you target different states precisely.
  </Accordion>

  <Accordion id="checkbox-performance" title="Do lots of checkboxes impact performance?">
    Individual checkboxes are lightweight, but hundreds in a list might be slow. For large datasets, consider virtualization or pagination. The JavaScript component itself is efficient—performance issues usually come from too many DOM elements or complex change handlers.
  </Accordion>

  <Accordion id="checkbox-controlled-vs-uncontrolled" title="Should I use controlled or uncontrolled checkboxes?">
    Use controlled (with `checked` prop) when you need to manage state in parent components or with form libraries. Use uncontrolled (with `defaultChecked`) for simple cases where the checkbox manages its own state. The shadcn component supports both patterns.
  </Accordion>
</Accordions>