Skip to content

MUI Core /Base UI

A blank canvas for
total flexibility

Base UI gives you a set of foundational "headless" components that you can build with using any styling solution you choose—no need to override any default style engine or theme.

Get startedLearn Base UI

Why Base UI

Essential building blocks
for sleek and accessible UIs

Base UI abstracts away the more frustrating aspects of UI development—like accessibility, cross-browser compatibility, and event handling—so you can skip ahead to design implementation.

Completely unstyled

Nothing to override—start fresh with any style solution or design system.

Alternative to libraries such as:


Unstyled components

Choose your own
CSS adventure

Base UI's skeletal components give you a sturdy foundation to apply custom styles with ease. With no defaults to override, you're free to start from scratch using vanilla CSS, Tailwind CSS, MUI System, or any other framework you prefer.

TabsButtonInputMenuSliderMuch more
First page
import { TabsUnstyled } from '@mui/base/Tabs';
import { TabsListUnstyled } from '@mui/base/TabsList';
import { TabPanelUnstyled } from '@mui/base/TabPanel';
import { TabUnstyled } from '@mui/base/Tab';
import { styled } from '@mui/system';

const StyledTabsList = styled('div')`
  min-width: 300px;
  background-color: var(--palette-primary);
  border-radius: 12px;
  margin-bottom: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  align-content: space-between;
  box-shadow: var(--shadow);
`;

const StyledTabPanel = styled('div')`
  width: 100%;
  font-family: 'IBM Plex Sans', sans-serif;
  font-size: 0.875rem;
`;

const StyledTab = styled('button')`
  font-family: 'IBM Plex Sans', sans-serif;
  color: white;
  cursor: pointer;
  font-size: 0.875rem;
  font-weight: bold;
  background-color: transparent;
  width: 100%;
  padding: 12px;
  margin: 6px 6px;
  border: none;
  border-radius: 7px;
  display: flex;
  justify-content: center;

  &:hover {
    background-color: var(--palette-primary-light);
  }

  &:focus-visible {
    color: #FFF;
    outline: 3px solid var(--focus-ring);
  }

  &.Mui-selected {
    background-color: #FFF;
    color: var(--palette-primary);
  }
`;

<TabsUnstyled selectionFollowsFocus defaultValue={0}>
  <TabsListUnstyled slots={{ root: StyledTabsList }}>
    <TabUnstyled slots={{ root: StyledTab }}>One</TabUnstyled>
    <TabUnstyled slots={{ root: StyledTab }}>Two</TabUnstyled>
    <TabUnstyled slots={{ root: StyledTab }}>Three</TabUnstyled>
  </TabsListUnstyled>
  <TabPanelUnstyled slots={{ root: StyledTabPanel }} value={0}>
    First page
  </TabPanelUnstyled>
  <TabPanelUnstyled slots={{ root: StyledTabPanel }} value={1}>
    Second page
  </TabPanelUnstyled>
  <TabPanelUnstyled slots={{ root: StyledTabPanel }} value={2}>
    Third page
  </TabPanelUnstyled>
</TabsUnstyled>

Customization

Endless possibilities
with a lightweight API

With Base UI, you have the freedom to decide how much you want to customize a component's structure and style.

Applying custom CSS rulesYour CSS, your rules. With Base UI there are no styles to override, so you can start with a clean slate.Overriding subcomponent slotsDefault DOM structure doesn't suit your needs? Replace any node with the element you prefer using the `slots` prop.Creating custom components using hooksBase UI includes low-level hooks for adding functionality to your own fully custom-built components.
import clsx from 'clsx';
import { styled } from '@mui/system';
import { SwitchUnstyled } from '@mui/base/Switch';
import { useSwitch } from '@mui/base/useSwitch';

const StyledSwitchRoot = styled('span')(`
  font-size: 0;
  position: relative;
  display: inline-block;
  width: 40px;
  height: 24px;
  margin: 10px;
  cursor: pointer;
  border-radius: 16px;
  background: #A0AAB4;

  &.Mui-disabled {
    opacity: 0.4;
    cursor: not-allowed;
  }

  &.Mui-checked {
    background: #007FFF;
    & .MuiSwitch-thumb {
      left: 20px;
    }
  }

  &.Mui-focusVisible {
    outline: 2px solid #007FFF;
    outline-offset: 2px;
  }
`);

const StyledSwitchInput = styled('input')`
  cursor: inherit;
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  opacity: 0;
  z-index: 1;
  margin: 0;
`;

const StyledSwitchThumb = styled('span')`
  display: block;
  width: 16px;
  height: 16px;
  top: 4px;
  left: 4px;
  border-radius: 16px;
  background-color: #FFF;
  position: relative;
  transition-property: all;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 120ms;

  &.Mui-checked {
    left: 20px;
  }
`;

function SwitchFromHook(props) {
  const {
    getInputProps,
    checked,
    disabled,
    focusVisible,
  } = useSwitch(props);

  const stateClasses = {
    'Mui-checked': checked,
    'Mui-disabled': disabled,
    'Mui-focusVisible': focusVisible,
  };

  return (
    <StyledSwitchRoot className={clsx(stateClasses)}>
      <StyledSwitchThumb className={clsx(stateClasses)} />
      <StyledSwitchInput {...getInputProps()} aria-label="Demo switch" />
    </StyledSwitchRoot>
  );
}

function App() {
  return (
    <SwitchUnstyled
      slots={{
        root: StyledSwitchRoot,
        input: StyledSwitchInput,
        thumb: StyledSwitchThumb,
      }}
      slotProps={{
        input: { 'aria-label': 'Demo switch' },
      }}
    />
    <SwitchFromHook />
  )
}

Nhost's dashboard

Screenshot displaying part of the Nhost dashboard that used Base UI to be built.

Nhost's new dashboard, powered by Base UI   /  View the blog post

“After considering various options, we decided to migrate our custom components to Material UI, and that's when we discovered Base UI. As a set of headless components, it offered exactly what we needed to implement our design system while maintaining full customizability. The focus on accessibility was also a big plus, as it ensured that our dashboard was usable by everyone. Low-level component hooks were just the icing on the cake.”


Szilárd Dóró's profile picture

Szilárd Dóró

Senior Software Engineer


Community

Join our global community

Base UI wouldn't be possible without our global community of contributors. Join us today to get help when you need it, and lend a hand when you can.

  • Base UI vs. Material UI

    Base UI features many of the same components as Material UI, but without the Material Design implementation.

  • Does it come with styles?

    Base UI is not packaged with any default theme or built-in style engine. This makes it a great choice if you need complete control over how your app's CSS is implemented.