Theme UI
Theme UI is a robust library for constructing themeable user interfaces, leveraging constraint-based design principles to build cohesive design systems, component libraries, and web applications. It serves as the spiritual successor and next evolution of Styled System, offering a flexible API designed for developer ergonomics. The current stable version is 0.17.4. While specific release cadences for major versions aren't fixed, the project sees active development with frequent minor and develop releases, indicating an ongoing commitment to bug fixes and incremental improvements on the 0.x branch. Key differentiators include its powerful `sx` prop for direct, theme-based styling, broad compatibility with virtually any UI component library, built-in support for dark modes, primitive page layout components, and deep integration with popular tools like Gatsby and MDX for content styling. It is built on Emotion for efficient scoped styles and adheres to a standard Theme Specification, promoting interoperability and a consistent design language across projects, making it ideal for large-scale design system implementation.
Common errors
-
Error: No ThemeProvider found.
cause Theme UI components were rendered without being wrapped in a ThemeProvider.fixWrap your root component or the section using Theme UI with `<ThemeProvider theme={yourTheme}>`. -
Property 'sx' does not exist on type 'IntrinsicElements...' (TypeScript error)
cause TypeScript compiler cannot find the `sx` prop definition for standard HTML elements or custom components.fixEnsure you have `@types/theme-ui` installed and that your `tsconfig.json` includes `theme-ui` types. You might also need to configure a custom `jsx` pragma in your `tsconfig.json` or Babel configuration. -
React Hook 'useThemeUI' cannot be called inside a class component. React Hooks can only be called inside of a function component.
cause `useThemeUI` is a React Hook and can only be used within functional components or other custom hooks, not within class components.fixRefactor your component to be a functional component or pass the theme down as props from a parent functional component that uses `useThemeUI`.
Warnings
- gotcha Theme UI relies heavily on a `ThemeProvider` at the root of your application. Components styled with `sx` or `variant` props will not function correctly or throw errors if they are rendered outside of a `ThemeProvider` context.
- gotcha The `sx` prop in Theme UI does not directly override all CSS properties in the same way inline styles might. It's designed to work with theme scales and provides shorthands. Mixing `sx` with direct CSS or `className` from other libraries can lead to unexpected specificity issues.
- gotcha When upgrading Theme UI, particularly across minor versions (e.g., from 0.16 to 0.17), always review the release notes. While 0.x releases generally aim for backward compatibility, minor breaking changes or API deprecations can occur due to its active development and experimental features.
- breaking Theme UI requires `react` version 18 or higher and `@emotion/react` version 11.1.1 or higher as peer dependencies. Older versions of these packages will cause runtime errors or compilation failures.
Install
-
npm install theme-ui -
yarn add theme-ui -
pnpm add theme-ui
Imports
- ThemeProvider
const { ThemeProvider } = require('theme-ui')import { ThemeProvider } from 'theme-ui' - Box
import Box from 'theme-ui'
import { Box } from 'theme-ui' - useThemeUI
const useThemeUI = require('theme-ui').useThemeUIimport { useThemeUI } from 'theme-ui'
Quickstart
import React from 'react';
import { ThemeProvider, Box, Text } from 'theme-ui';
const customTheme = {
colors: {
text: '#000',
background: '#fff',
primary: '#07c',
secondary: '#05a',
modes: {
dark: {
text: '#fff',
background: '#000',
primary: '#0cf',
secondary: '#09f',
},
},
},
fonts: {
body: 'system-ui, sans-serif',
heading: 'Georgia, serif',
},
text: {
heading: {
fontFamily: 'heading',
lineHeight: 'heading',
fontWeight: 'heading',
fontSize: [4, 5, 6],
},
},
buttons: {
primary: {
color: 'background',
bg: 'primary',
'&:hover': {
bg: 'secondary',
},
},
},
styles: {
root: {
fontFamily: 'body',
color: 'text',
bg: 'background',
},
},
};
const App = () => (
<ThemeProvider theme={customTheme}>
<Box sx={{
maxWidth: 960,
mx: 'auto',
px: [3, 4],
py: 4,
bg: 'background',
color: 'text',
}}>
<Text as="h1" sx={{ variant: 'text.heading', color: 'primary' }}>
Welcome to Theme UI!
</Text>
<Text sx={{ fontSize: [2, 3] }}>
This is an example of a themed application using Theme UI's `sx` prop and `ThemeProvider`.
The styles are derived from the `customTheme` object, enabling responsive and consistent design.
</Text>
<Box as="button" sx={{ variant: 'buttons.primary', mt: 4, p: 3, borderRadius: 4 }}>
Click Me
</Box>
</Box>
</ThemeProvider>
);
export default App;