Themes & CSS Variables
The library ships two classname maps — defaultStyles (light) and darkStyles — and exposes every color as a --sjv-* CSS custom property so you can retheme without swapping the style prop.
Built-in Themes
<script lang="ts">
import { JsonView, defaultStyles, darkStyles } from '@humanspeak/svelte-json-view-lite'
</script>
<!-- Light (default) -->
<JsonView data={payload} />
<!-- Dark -->
<JsonView data={payload} style={darkStyles} /><script lang="ts">
import { JsonView, defaultStyles, darkStyles } from '@humanspeak/svelte-json-view-lite'
</script>
<!-- Light (default) -->
<JsonView data={payload} />
<!-- Dark -->
<JsonView data={payload} style={darkStyles} />Both exports conform to StyleProps. Spread them to patch individual keys:
<JsonView
data={payload}
style={{ ...defaultStyles, quotesForFieldNames: true, stringifyStringValues: true }}
/><JsonView
data={payload}
style={{ ...defaultStyles, quotesForFieldNames: true, stringifyStringValues: true }}
/>CSS Variable Tokens
Every color used by the viewer is declared on the container element as a --sjv-* custom property. Overriding any token cascades to every descendant that reads it.
| Token | Applies to | Light default | Dark default |
|---|---|---|---|
--sjv-background | Container background | #eee | rgb(0, 43, 54) |
--sjv-label | Field labels (keys) | #000000 | rgb(253, 246, 227) |
--sjv-punctuation | Braces, brackets, colons, commas | #000000 | rgb(253, 246, 227) |
--sjv-string | String values | rgb(42, 63, 60) | rgb(203, 75, 22) |
--sjv-number | Number values | #0b75f5 | rgb(211, 54, 130) |
--sjv-boolean | Boolean values | rgb(70, 144, 56) | rgb(174, 129, 255) |
--sjv-null | null values | #df113a | rgb(129, 181, 172) |
--sjv-undefined | undefined values | #df113a | rgb(129, 181, 172) |
--sjv-other | bigint, Date, functions | #43413d | rgb(38, 139, 210) |
--sjv-expander | Arrow glyphs + collapsed summary | #000000 | rgb(253, 246, 227) |
Global Overrides
Set tokens on :root to retheme every instance on the page:
:root {
--sjv-string: lavender;
--sjv-number: var(--brand-500);
--sjv-background: transparent;
}:root {
--sjv-string: lavender;
--sjv-number: var(--brand-500);
--sjv-background: transparent;
}Because the defaults are declared on the container (not fallbacks on var()), inheritance from :root alone does not win against the per-container declarations. Use a selector with higher specificity, or target the tree element directly:
[role='tree'] {
--sjv-background: transparent;
}[role='tree'] {
--sjv-background: transparent;
}Per-Instance Overrides
Scope custom tokens to one viewer with a wrapping class. The library’s container selector has specificity (0,1,0); anything with (0,2,0) or higher wins without !important:
<div class="payload-view">
<JsonView data={payload} />
</div>
<style>
.payload-view :global([role='tree']) {
--sjv-background: transparent;
--sjv-label: var(--color-foreground);
--sjv-string: #f59e0b;
--sjv-number: var(--color-brand-500);
}
</style><div class="payload-view">
<JsonView data={payload} />
</div>
<style>
.payload-view :global([role='tree']) {
--sjv-background: transparent;
--sjv-label: var(--color-foreground);
--sjv-string: #f59e0b;
--sjv-number: var(--color-brand-500);
}
</style>This is exactly how the landing page’s live playground tracks light and dark modes — it maps --sjv-* tokens to the site’s design-system variables.
Dark Mode with mode-watcher
If you use mode-watcher, derive the style prop from the current mode:
<script lang="ts">
import { JsonView, defaultStyles, darkStyles } from '@humanspeak/svelte-json-view-lite'
import { mode } from 'mode-watcher'
const theme = $derived(mode.current === 'dark' ? darkStyles : defaultStyles)
</script>
<JsonView data={payload} style={theme} /><script lang="ts">
import { JsonView, defaultStyles, darkStyles } from '@humanspeak/svelte-json-view-lite'
import { mode } from 'mode-watcher'
const theme = $derived(mode.current === 'dark' ? darkStyles : defaultStyles)
</script>
<JsonView data={payload} style={theme} />Or skip the prop swap entirely and let CSS variables switch based on a root class:
:root { --sjv-background: #eee; }
.dark { --sjv-background: #0f172a; }:root { --sjv-background: #eee; }
.dark { --sjv-background: #0f172a; }Boolean Style Options
StyleProps has three booleans that affect rendering regardless of which palette you pick:
| Option | Effect |
|---|---|
noQuotesForStringValues | Omits the " around string leaves |
quotesForFieldNames | Wraps field labels in " |
stringifyStringValues | Passes string values through JSON.stringify so control characters render as escapes |
<JsonView
data={payload}
style={{ ...defaultStyles, quotesForFieldNames: true, noQuotesForStringValues: true }}
/><JsonView
data={payload}
style={{ ...defaultStyles, quotesForFieldNames: true, noQuotesForStringValues: true }}
/>Related
- Types & snippets — the full
StylePropsshape - Snippet overrides — when theming isn’t enough and you need a custom renderer