Getting started — Svelte

Add Justin to a Svelte 5 / SvelteKit app.

Install

bun add @davidhorn/justin

Import the styles

Once, at the root of your app — usually in src/routes/+layout.svelte:

<script>
  import '@davidhorn/justin/styles';
</script>

This registers all design tokens as CSS custom properties (--color-primary, --spacing-4, --font-size-headline-md, …) and applies the ITCSS layers (reset, generic, elements, components, utilities).

Wire the icon plugin

DhIcon ships the full Lucide glyph set and serves each SVG as a per-file static asset on your own origin. Register the Vite plugin so the icons end up under /icons/:

// vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';
import { justinIcons } from '@davidhorn/justin/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [sveltekit(), justinIcons()]
});

Without it, every <DhIcon> 404s.

Use a component

<script>
  import { DhButton, DhTextInput } from '@davidhorn/justin';
  let name = $state('');
</script>

<DhTextInput bind:value={name} label="Your name" />
<DhButton variant="primary" text="Submit" onclick={() => alert(name)} />

Granular imports

The package exposes per-component and per-layer subpaths so you can cherry-pick when you don’t want the whole library. When importing a component’s CSS directly, also import @davidhorn/justin/styles/settings.css (or a per-group file under styles/settings/) so the design-token custom properties used by that CSS are defined.

Icon-only recipe:

<script>
  // Just the icon component
  import DhIcon from '@davidhorn/justin/components/Icon.svelte';
  // Tokens (so the icon picks up your app's theme)
  import '@davidhorn/justin/styles/settings.css';
  // The icon's component CSS only
  import '@davidhorn/justin/styles/components/icon.css';
</script>

<DhIcon name="search" />

Tokens-only (build your own components on top):

<script>
  import '@davidhorn/justin/styles/settings.css';
  // or one group at a time:
  // import '@davidhorn/justin/styles/settings/colors.css';
</script>

Available CSS subpaths

SubpathShips
@davidhorn/justin/styles.cssEverything (tokens + reset + elements + components)
@davidhorn/justin/styles/settings.cssTokens only
@davidhorn/justin/styles/settings/<group>.cssOne token group (colors, radius, spacing, typography)
@davidhorn/justin/styles/generic.cssReset + box-sizing
@davidhorn/justin/styles/elements.cssBase HTML element styles
@davidhorn/justin/styles/components.cssAll component CSS, no tokens
@davidhorn/justin/styles/components/<name>.cssOne component’s CSS

Light and dark mode

By default, components follow the user’s prefers-color-scheme. To force a theme, set data-theme="light" or data-theme="dark" on <html>. The docs site’s theme picker uses the same key (localStorage.dh-demo-theme) — share that mechanism in your own app if you want a manual override.

What’s next