Skip to content

DevTools

@theme-kit/devtools

@theme-kit/devtools ships an inspector, a plugin, and a ready-made panel for debugging every theme change. It records lifecycle events, performance timings, state snapshots and the flattened CSS-variable output of the active theme.

1Quick start

Attach the plugin to your runtime and a panel to your page.
setup
ts
1import { createThemeRuntime } from "@theme-kit/core";
2import { createDevToolsPlugin, createDevToolsPanel } from "@theme-kit/devtools";
3
4const runtime = createThemeRuntime({
5  themes,
6  plugins: [createDevToolsPlugin()],
7});
8
9// Optional: mount the UI panel anywhere
10const panel = createDevToolsPanel(
11  runtime.plugins.get("devtools-inspector") as any,
12);
13document.body.appendChild(panel);

2createDevToolsPlugin(options)

A Theme Kit plugin that instantiates an inspector, binds it to the runtime and exposes it on window.__THEME_KIT_DEVTOOLS__ so extensions can find it.
plugin
ts
1const plugin = createDevToolsPlugin({ maxEntries: 200, maxPerfEntries: 100 });
2
3const runtime = createThemeRuntime({ themes, plugins: [plugin] });
4
5plugin.getInspector().getState();
6// {
7//   currentTheme: ThemeDefinition,
8//   selection: { mode, family },
9//   history: [{ index, point: { theme, selection } }],
10//   entries: [{ type, timestamp, label, data }],
11//   performance: [{ duration, type, timestamp }],
12//   cssVariables: { "--theme-color-primary": "#6366f1", ... },
13// }
Internally it subscribes to beforeThemeChange / afterThemeChange to record perf entries and emits a theme-change event entry on every switch.

3createDevToolsInspector(options)

The standalone recorder — use it directly if you are not going through the plugin. Records theme-change entries, lifecycle performance events and state snapshots.
inspector
ts
1const inspector = createDevToolsInspector();
2
3// Read what has happened
4inspector.getEntries();
5// [{ type: "theme-change", timestamp: 1712345678901, label: "Theme changed", data: {} }]
6
7inspector.getPerformance();
8// [{ duration: 0, type: "afterThemeChange", timestamp: 1712345678901 }]
9
10// Jump through history
11inspector.jump(0); // restores snapshot at index 0
12
13// Inspect live state
14inspector.getState();
15inspector.getCSSVariables();
16
17// Export
18inspector.exportState(); // JSON string of the full state
19inspector.exportCSS();   // { "--theme-color-primary": "#6366f1", ... }
20
21inspector.clearEntries();
22inspector.clearPerformance();
23inspector.destroy();
Capped at maxEntries (default 200) and maxPerfEntries (default 100).

4createDevToolsPanel(inspector)

Renders a floating, framework-free panel (plain DOM, no dependencies) with five tabs.
panel
ts
const panel = createDevToolsPanel(inspector);
document.body.appendChild(panel);
Panel tabs
I
InspectorThe current theme and selection as pretty-printed JSON
E
EventsChronological lifecycle event entries
P
PerfbeforeThemeChange / afterThemeChange timings as bars
C
CSS VarsThe flattened --theme-* variables with color swatches
H
HistoryEvery snapshot with a one-click Jump to restore it

Footer buttons clear events/perf and export the state to JSON or the CSS variables to a .css file.

5Global hook

Every inspector registered via the plugin is added to a Set on window.__THEME_KIT_DEVTOOLS__ so a browser extension or your own code can enumerate and inspect all live runtimes.
global hook
ts
1declare global {
2  interface Window {
3    __THEME_KIT_DEVTOOLS__?: Set<{
4      getState(): unknown;
5      getEntries(): unknown[];
6      getPerformance(): unknown[];
7    }>;
8  }
9}
10
11for (const inspector of window.__THEME_KIT_DEVTOOLS__ ?? []) {
12  console.log(inspector.getState());
13}

6Entry types

Every recorded entry has a type field.
TypeMeaning
theme-changeThe active theme changed
mode-changeThe mode changed (light / dark / system)
family-changeThe family changed (e.g. plum → mint)
persistSelection was persisted to storage
restoreA snapshot was restored (undo / redo / jump)
batchAn atomic batched update ran
DevTools — Theme Kit