Checkbox 
Checkbox gives users a binary choice between multiple options in a series.
Show code 'use client' ; import  *  as  React  from  'react' ; import  {  Checkbox  }  from  '@base-ui-components/react/Checkbox' ; import  {  useTheme  }  from  '@mui/system' ; export  default  function  UnstyledCheckboxIntroduction () {   return  (     < div  style = {{ display:  'flex' , gap:  12  }}>       < Checkbox.Root         className = "Checkbox"         aria-label = "Basic checkbox, on by default"         defaultChecked       >         < Checkbox.Indicator  className = "Checkbox-indicator" >           < CheckIcon  className = "Checkbox-icon"  />         </ Checkbox.Indicator >       </ Checkbox.Root >       < Checkbox.Root         className = "Checkbox"         aria-label = "Basic checkbox, off by default"       >         < Checkbox.Indicator  className = "Checkbox-indicator" >           < CheckIcon  className = "Checkbox-icon"  />         </ Checkbox.Indicator >       </ Checkbox.Root >       < Checkbox.Root         className = "Checkbox"         aria-label = "Disabled checkbox, on by default"         defaultChecked         disabled       >         < Checkbox.Indicator  className = "Checkbox-indicator" >           < CheckIcon  className = "Checkbox-icon"  />         </ Checkbox.Indicator >       </ Checkbox.Root >       < Checkbox.Root         className = "Checkbox"         aria-label = "Disabled checkbox, off by default"         disabled       >         < Checkbox.Indicator  className = "Checkbox-indicator" >           < CheckIcon  className = "Checkbox-icon"  />         </ Checkbox.Indicator >       </ Checkbox.Root >       < Styles  />     </ div >   ); } const  grey  =  {   100 :  '#E5EAF2' ,   300 :  '#C7D0DD' ,   500 :  '#9DA8B7' ,   600 :  '#6B7A90' ,   800 :  '#303740' ,   900 :  '#1C2025' , }; function  useIsDarkMode () {   const  theme  =  useTheme ();   return  theme . palette . mode  ===  'dark' ; } function  Styles () {   // Replace this with your app logic for determining dark mode   const  isDarkMode  =  useIsDarkMode ();   return  (     < style >       { `       .Checkbox {         all: unset;         box-sizing: border-box;         text-align: center;         width: 24px;         height: 24px;         padding: 0;         border-radius: 4px;         border: 2px solid ${ grey [ 600 ] };         background: none;         transition-property: background, border-color;         transition-duration: 0.15s;       }       .Checkbox[data-disabled] {         opacity: 0.4;         cursor: not-allowed;       }       .Checkbox:focus-visible {         outline: 2px solid ${ isDarkMode  ?  grey [ 600 ]  :  grey [ 500 ] };         outline-offset: 2px;       }       .Checkbox[data-checked] {         border-color: ${ grey [ 800 ] };         background: ${ grey [ 800 ] };       }       .Checkbox-indicator {         height: 100%;         display: inline-block;         visibility: hidden;         color: ${ isDarkMode  ?  grey [ 900 ]  :  grey [ 100 ] };       }       .Checkbox-indicator[data-checked] {         visibility: visible;       }       .Checkbox-icon {         width: 100%;         height: 100%;       }       @media (prefers-color-scheme: dark) {         .Checkbox {           border-color: ${ grey [ 500 ] };         }         .Checkbox[data-checked] {           border-color: ${ grey [ 300 ] };           background: ${ grey [ 300 ] };         }         .Checkbox:hover:not([data-disabled]) {           border-color: ${ grey [ 100 ] };         }         .Checkbox-indicator {           color: ${ grey [ 900 ] };         }       }     ` }     </ style >   ); } function  CheckIcon ( props :  React . SVGProps < SVGSVGElement >) {   return  (     < svg       xmlns = "http://www.w3.org/2000/svg"       { ... props }       width = "24"       height = "24"       viewBox = "0 0 24 24"       fill = "none"     >       < path         d = "M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"         fill = "currentColor"       />     </ svg >   ); } Base UI components are all available as a single package.
npm pnpm Yarn 
npm install @base-ui-components/react 
Once you have the package installed, import the component.
import { Checkbox } from '@base-ui-components/react/Checkbox'; Checkbox is composed of two components:
<Checkbox.Root /> renders a <button>.<Checkbox.Indicator /> renders a <span> for providing a visual indicator. You could place an icon inside this component. 
< Checkbox.Root >   < Checkbox.Indicator  /> </ Checkbox.Root > To make the Checkbox indeterminate, add the indeterminate prop to override the appearance of the Checkbox. The Checkbox remains in an indeterminate state regardless of user interaction until set back to false.
Show code 'use client' ; import  *  as  React  from  'react' ; import  {  styled  }  from  '@mui/system' ; import  {  Checkbox  as  BaseCheckbox  }  from  '@base-ui-components/react/Checkbox' ; export  default  function  UnstyledCheckboxIndeterminate () {   return  (     < div  style = {{ display:  'flex' , gap:  12  }}>       < Checkbox  aria-label = "Indeterminate checkbox"  indeterminate >         < Indicator >           < HorizontalRuleIcon  />         </ Indicator >       </ Checkbox >       < Checkbox  aria-label = "Indeterminate disabled checkbox"  indeterminate  disabled >         < Indicator >           < HorizontalRuleIcon  />         </ Indicator >       </ Checkbox >     </ div >   ); } const  blue  =  {   400 :  '#3399FF' ,   600 :  '#0072E6' ,   800 :  '#004C99' , }; const  grey  =  {   100 :  '#E5EAF2' , }; const  Checkbox  =  styled ( BaseCheckbox . Root )(   ({  theme  })  =>  `     width: 24px;     height: 24px;     padding: 0;     border-radius: 4px;     border: 2px solid ${ blue [ 600 ] };     background: none;     transition-property: background, border-color;     transition-duration: 0.15s;     outline: none;     &[data-disabled] {       opacity: 0.4;       cursor: not-allowed;     }     &:focus-visible {       outline: 2px solid ${ theme . palette . mode  ===  'dark'  ?  blue [ 800 ]  :  blue [ 400 ] };       outline-offset: 2px;     }     &[data-checked],     &[data-indeterminate] {       border-color: transparent;       background: ${ blue [ 600 ] };     }   ` , ); const  HorizontalRuleIcon  =  styled ( function  HorizontalRuleIcon (   props :  React . SVGProps < SVGSVGElement >, ) {   return  (     < svg       xmlns = "http://www.w3.org/2000/svg"       { ... props }       width = "24"       height = "24"       viewBox = "0 0 24 24"       fill = "none"     >       < path  d = "M4 11h16v2H4z"  fill = "currentColor"  />     </ svg >   ); }) `   height: 100%;   width: 100%; ` ; const  Indicator  =  styled ( BaseCheckbox . Indicator ) `   color: ${ grey [ 100 ] };   height: 100%;   display: inline-block;   visibility: hidden;   &[data-checked],   &[data-indeterminate] {     visibility: visible;   } ` ; The primary use case for an indeterminate checkbox is representing the state of a parent checkbox where only some of its children are checked.
Show code 'use client' ; import  *  as  React  from  'react' ; import  {  styled  }  from  '@mui/system' ; import  {  Checkbox  as  BaseCheckbox  }  from  '@base-ui-components/react/Checkbox' ; const  colors  =  [ 'Red' ,  'Green' ,  'Blue' ]; export  default  function  UnstyledCheckboxIndeterminateGroup () {   const  [ checkedValues ,  setCheckedValues ]  =  React . useState ([ 'Green' ]);   const  isChecked  =  checkedValues . length  ===  colors . length ;   const  isIndeterminate  =     checkedValues . length  !==  colors . length  &&  checkedValues . length  >  0 ;   const  id  =  React . useId ();   return  (     < div  style = {{ display:  'flex' , flexDirection:  'column'  }}>       < ListRoot >         < Checkbox           id = { id }           aria-controls = { colors . map (( color )  =>  `${ id }-${ color }` ). join ( ' ' )}           indeterminate = { isIndeterminate }           checked = { isChecked }           onCheckedChange = {( checked )  =>  {             setCheckedValues ( checked  ?  colors  :  []);           }}         >           < Indicator >             { isIndeterminate  ?  < HorizontalRuleIcon  />  :  < CheckIcon  />}           </ Indicator >         </ Checkbox >         < Label  htmlFor = { id }  onMouseDown = {( event )  =>  event . preventDefault ()}>           Colors         </ Label >       </ ListRoot >       < List >         { colors . map (( color )  =>  (           < ListItem  key = { color }>             < Checkbox               id = { `${ id }-${ color }` }               checked = { checkedValues . includes ( color )}               onCheckedChange = {( checked )  =>  {                 const  newCheckedValues  =  [ ... checkedValues ];                 if  ( checked ) {                   newCheckedValues . push ( color );                 }  else  {                   newCheckedValues . splice ( newCheckedValues . indexOf ( color ),  1 );                 }                 setCheckedValues ( newCheckedValues );               }}             >               < Indicator >                 < CheckIcon  />               </ Indicator >             </ Checkbox >             < Label               htmlFor = { `${ id }-${ color }` }               onMouseDown = {( event )  =>  event . preventDefault ()}             >               { color }             </ Label >           </ ListItem >         ))}       </ List >     </ div >   ); } const  blue  =  {   400 :  '#3399FF' ,   600 :  '#0072E6' ,   800 :  '#004C99' , }; const  grey  =  {   100 :  '#E5EAF2' ,   400 :  '#B0B8C4' ,   800 :  '#303740' , }; const  Checkbox  =  styled ( BaseCheckbox . Root )(   ({  theme  })  =>  `     width: 24px;     height: 24px;     padding: 0;     border-radius: 4px;     border: 2px solid ${ blue [ 600 ] };     background: none;     transition-property: background, border-color;     transition-duration: 0.15s;     outline: none;     &[data-disabled] {       opacity: 0.4;       cursor: not-allowed;     }     &:focus-visible {       outline: 2px solid ${ theme . palette . mode  ===  'dark'  ?  blue [ 800 ]  :  blue [ 400 ] };       outline-offset: 2px;     }     &[data-checked], &[data-indeterminate] {       border-color: transparent;       background: ${ blue [ 600 ] };     }   ` , ); const  HorizontalRuleIcon  =  styled ( function  HorizontalRuleIcon (   props :  React . SVGProps < SVGSVGElement >, ) {   return  (     < svg       xmlns = "http://www.w3.org/2000/svg"       { ... props }       width = "24"       height = "24"       viewBox = "0 0 24 24"       fill = "none"     >       < path  d = "M4 11h16v2H4z"  fill = "currentColor"  />     </ svg >   ); }) `   height: 100%;   width: 100%; ` ; const  CheckIcon  =  styled ( function  CheckIcon ( props :  React . SVGProps < SVGSVGElement >) {   return  (     < svg       xmlns = "http://www.w3.org/2000/svg"       { ... props }       width = "24"       height = "24"       viewBox = "0 0 24 24"       fill = "none"     >       < path         d = "M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"         fill = "currentColor"       />     </ svg >   ); }) `   height: 100%;   width: 100%; ` ; const  Indicator  =  styled ( BaseCheckbox . Indicator ) `   height: 100%;   display: inline-block;   visibility: hidden;   color: ${ grey [ 100 ] };   &[data-checked],   &[data-indeterminate] {     visibility: visible;   } ` ; const  ListRoot  =  styled ( 'div' ) `   display: flex;   align-items: center;   margin-bottom: 8px; ` ; const  List  =  styled ( 'ul' ) `   list-style: none;   padding: 0;   margin: 0;   margin-left: 32px; ` ; const  ListItem  =  styled ( 'li' ) `   display: flex;   align-items: center;   &:not(:last-child) {     margin-bottom: 8px;   } ` ; const  Label  =  styled ( 'label' )(   ({  theme  })  =>  `     padding-left: 8px;     color: ${ theme . palette . mode  ===  'dark'  ?  grey [ 400 ]  :  grey [ 800 ] };   ` , ); It's a visual-only  state, so its internal checked state can still be changed.
Use the render prop to override the rendered checkbox or indicator element with your own components.
< Checkbox.Root  render = {( props )  =>  < MyCheckbox  { ... props } />}>   < Checkbox.Indicator  render = {( props )  =>  < MyCheckboxIndicator  { ... props } />} /> </ Checkbox.Root > Ensure the Checkbox has an accessible name via a <label> element.
< Checkbox.Root  id = "my-checkbox" >   < Checkbox.Indicator  /> </ Checkbox.Root > < label  htmlFor = "my-checkbox" >   My label </ label > API Reference CheckboxRoot The foundation for building custom-styled checkboxes.
Prop Type Default Description checkedboolundefinedIf true, the component is checked. classNameunionClass names applied to the element or a function that returns them based on the component's state. defaultCheckedboolfalseThe default checked state. Use when the component is not controlled. disabledboolfalseIf true, the component is disabled. indeterminateboolfalseIf true, the checkbox will be indeterminate. inputRefunionThe ref to the input element. namestringundefinedName of the underlying input element. onCheckedChangefuncCallback fired when the checked state is changed. parentboolfalseIf true, the checkbox is a parent checkbox for a group of child checkboxes. readOnlyboolfalseIf true, the component is read only. renderunionA function to customize rendering of the component. requiredboolfalseIf true, the input element is required. 
CheckboxIndicator The indicator part of the Checkbox.
Prop Type Default Description classNameunionClass names applied to the element or a function that returns them based on the component's state. keepMountedbooltrueIf true, the indicator stays mounted when unchecked. Useful for CSS animations. renderunionA function to customize rendering of the component.