2.0 alpha
These docs describe 2.0. Install it with @once-ui-system/core@alpha.
On 1.8.x? Read the 1.x docs
TrademarkTrademarkDocs
Ctrl k
Search docs...
Contexts

ThemeProvider

Updated: June 30, 2026
View on GitHub
The ThemeProvider is a context that persists user theme preferences and syncs with the system’s light/dark setting. It provides a useTheme hook to manage theme state at runtime and sets data attributes on the <html> element. Wrap your app with ThemeProvider and pass the style configuration as props. You can create a single source of truth for all style configuration in a separate file, for example once-ui.config.js. We also recommend using a Providers component to wrap your app. If you don't pass any props to the ThemeProvider, it will fall back to defaults. If the visitor has theme preferences (saved in localStorage), the ThemeProvider will use those. To force a theme, set theme on the ThemeProvider as light or dark. Use a custom color palette for the data-brand, data-accent and data-neutral attributes by setting their values to custom and loading the CSS variables in the layout.tsx file. You can generate palettes using the Once UI customize page. Access and modify theme state with useTheme: Add the <ThemeInit> component to the <head> to set the initial theme before hydration in layout.tsx. It will prevent flash of unstyled content (FOUC). Visit the ThemeSwitcher or StylePanel page for native, out-of-the-box ThemeProvider implementation with localStorage persistence. Use these components to provide user-facing style controls or to quickly test different styles during development.
PageCustomize page theme
Theme
Shape
ColorCustomize color schemes
Brand
Accent
Neutral
Solid styleCustomize the appearance of interactive elements
Style
Effect
AdvancedCustomize advanced styling options
Surface
Scaling
Data Style
Transition
The ThemeProvider relies on data attributes to set theme and style preferences. Data modes are inherited from the parent and can be applied to any semantic HTML element, providing simple, seamless style overrides. Just add the data-theme, data-neutral, data-brand, data-accent, data-border, data-surface, data-solid, data-solid-style, data-transition or data-scaling attributes to any semantic HTML element to override its default style. Style choices are mirrored into localStorage under data-<kebab-key>. Set persistence to change that:
  • "local" — the default described above.
  • "none" — choices apply to the document but are not stored. Use this when a host owns the state, such as an editor holding an unsaved draft.
  • an adapter — route persistence somewhere else, such as a database.
get runs during hydration, so it must be synchronous — an await there would show a flash of the wrong theme. When the values live somewhere async, omit get and seed the provider through its props from the server instead. set and remove may return a promise; nothing waits on them.
Prop
Type
Default
children
React.ReactNode
theme
systemdarklight
system
brand
blueindigovioletmagentapinkredorangeyellowmossgreenemeraldaquacyancustom
blue
accent
blueindigovioletmagentapinkredorangeyellowmossgreenemeraldaquacyancustom
indigo
neutral
sandgrayslatecustom
gray
solid
colorcontrastinverse
contrast
solidStyle
flatplastic
flat
border
roundedplayfulconservative
playful
surface
filledtranslucent
translucent
transition
allmicromacronone
all
scaling
9095100105110
100
Returns { theme, resolvedTheme, setTheme }.
Prop
Type
Default
theme
Current theme setting
Theme
resolvedTheme
Actual resolved theme
"light" | "dark"
setTheme
Update theme
(theme: Theme) => void
Returns all style options plus setStyle.
Prop
Type
Default
theme
Theme
neutral
NeutralColor | "custom"
brand
Schemes | "custom"
accent
Schemes | "custom"
solid
SolidType
solidStyle
SolidStyle
border
BorderStyle
surface
SurfaceStyle
transition
TransitionStyle
scaling
ScalingSize
setStyle
(style: Partial<StyleOptions>) => void
Edit this page on GitHub
TrademarkTrademark
Built with curiosity by Lorant One and the Design Engineers Club