--- title: Set up appearance preferences description: Aggregate appearance definitions and effects with the application's shared preferences. order: 1 toc: - id: provider title: Aggregate preferences - id: effects title: Register effects - id: theme-style title: Inject theme variables - id: persistence title: Persist updates --- ## Aggregate preferences {#provider} Build one complete preference definition map at the application boundary. Spread definitions from appearance, locale, keyboard, and other feature packages into this map, then create or load the initial values. ```tsx import { createDefaultPreferences, PreferencesProvider, } from "@workspace/preferences" import { appearancePreferenceDefinitions, appearancePreferenceEffect, } from "@workspace/appearance" const preferenceDefinitions = { ...appearancePreferenceDefinitions, ...localePreferenceDefinitions, } const initialPreferences = createDefaultPreferences(preferenceDefinitions) const preferenceEffects = [ appearancePreferenceEffect, localePreferenceEffect, ] as const export function Root({ children }: { children: React.ReactNode }) { return ( {children} ) } ``` `defaultAppearancePreferences` remains available when only the appearance slice is needed, but the definition map is the preferred source when several packages are combined. ## Register effects {#effects} `appearancePreferenceEffect` combines two exported callbacks: `applyAppearancePreferenceEffect` updates document classes and theme variables before paint, while `subscribeSystemThemePreferenceEffect` watches the operating-system theme after paint. Register the composed effect in the stable `effects` array passed to `PreferencesProvider`. ## Inject theme variables {#theme-style} Use `buildThemeStyleSheet` to generate the CSS variables for light, dark, and system modes. Keep the stable element ID so the appearance effect can update the same node when color preferences change. ```tsx import { buildThemeStyleSheet, THEME_STYLE_ELEMENT_ID, } from "@workspace/appearance" ;