ctx.theme stable
The theme domain — read the merged set of presets (core Dark/Light plus everything registered via ctx.registerThemePreset), switch the active theme, and manage the user's custom themes. The built-in theme picker and theme editor consume the domain through here rather than reaching into app state.
ctx.theme: ThemeServiceExample
// read reactively (e.g. via React's useSyncExternalStore)
const state = ctx.theme.getState();
state.presets; // core Dark/Light + every registered preset
state.activeId; // the active theme's id
state.customThemes; // the user's saved custom themes
// switch the active theme (a preset id or a custom theme id)
ctx.theme.setActive("gruvbox-dark");
// resolve an id to its base + effective vars (for a swatch / preview)
const { base, vars } = ctx.theme.resolve(state.activeId);
// observe changes (active theme, custom themes, or the set of presets)
const sub = ctx.theme.subscribe((s) => render(s));
sub.dispose();Methods
ThemeService (ctx.theme):
| Method | What it does |
|---|---|
getState() | Current frozen ThemeState. |
subscribe(listener) | Observe theme-state changes; returns a Disposable. |
setActive(id) | Switch the active theme by id (preset or custom). |
resolve(id) | Resolve an id to a ResolvedTheme (base + vars). |
saveCustom(theme) | Persist a custom theme to disk and reload the list. |
deleteCustom(id) | Delete a custom theme from disk and reload. |
reloadCustom() | Reload custom themes from disk. |
exportTheme(theme) | Strip the id for sharing/serialization. |
importTheme(data) | Validate JSON into a CustomTheme (fresh id). |
Types
ThemeService · ThemeState · ThemePreset · ResolvedTheme · CustomTheme · ThemeVars.
Notes
Presets are dynamic — part of the reactive state, not a static list, because extensions register and unregister them at runtime. Contributing a preset is a separate, registration-time concern: ctx.registerThemePreset. Core ships only Dark and Light as the always-present fallback; the bundled presets (Tokyo Night, Solarized Light, Gruvbox Dark) live in the theme-presets built-in extension, so the picker's bundled set is itself just contributions.