Skip to content

ThemeProvider

ThemeProvider

<ThemeProvider defaultTheme="light">
<App />
</ThemeProvider>
// inside any descendant:
const { theme, toggle } = useTheme();
<Button onPress={toggle}>Switch to {theme === 'light' ? 'dark' : 'light'}</Button>

SSR

When rendering on the server, set data-theme on <html> yourself to avoid a flash. ThemeProvider with rootElement="document" will reconcile after hydration.

Install: @helixui/core

import { ThemeProvider, useTheme } from '@helixui/core'

status: stable · since: 0.1.0

Tags: theme, light, dark, provider

Anatomy

<ThemeProvider theme="dark">
⟨all components inherit data-theme=dark⟩
</ThemeProvider>

Layout

  • displayblock
  • widthauto
  • heightauto
  • intrinsicSizeunstyled wrapper; sets data-theme on root
  • stackabletrue
  • fullBleedfalse

Visual

A presentational wrapper that toggles data-theme="light" or data-theme="dark" on a wrapping element. All helixui tokens are scoped to that attribute.

Props

NameTypeDefaultDescription
theme'light' | 'dark'Controlled theme.
defaultTheme'light' | 'dark'lightInitial theme when uncontrolled.
rootElement'document' | 'wrapper'documentWhere to apply data-theme. document writes to <html>. wrapper renders a div.
onChange(theme: Theme) => voidTheme change handler.

Slots

  • children — your app

Tokens used

color.text.primary, color.bg.surface.default

Accessibility

Notes

  • Theme switch should respect prefers-color-scheme on first load — wire that into your defaultTheme.
  • Avoid mounting two ThemeProviders with different themes; tokens cascade by attribute.

Composes with

ComponentRelationNote
HelixUIDNAProviderchildDNA tunes the genome inside a chosen theme.

Prompt examples

These are the AI prompt → JSX mappings used by the helixui prompt DSL and integrations like Cursor / Claude Code.

toggle dark mode

“wrap the app for theme switching”

<ThemeProvider theme={theme}>
<App />
</ThemeProvider>