Skip to content
Sveltier
Mode

Alpha · Svelte 5 · Built for AI coding agents

Your agent writes it. Sveltier gets it right.

The UI framework for coding agents. One typed vocabulary they cannot misuse, docs generated from the types they read, and errors that tell them the fix. What they build comes out accessible, consistent and polished, whichever model wrote it.

Agent session Scripted replay
You

Build a portfolio card: the total value, today’s change, a period switcher and the three holdings. Make it feel premium.

  1. Read llms-full.txt: props of every component
  2. Chose Card, Chip, SegmentedControl, List, Avatar
  3. Wrote Portfolio.svelte, 43 lines
  4. svelte-check: 0 errors
Portfolio.svelte
<script lang="ts">
  import { Avatar, Card, Chip, List, ListItem, SegmentedControl } from 'sveltier';

  type Period = '1D' | '1W' | '1M' | '1Y';

  const periods = (['1D', '1W', '1M', '1Y'] as const).map((value) => ({ value, label: value }));
  const holdings = [
    { id: 'eq', name: 'World equity', detail: '62% · index fund', value: '$153,894.10' },
    { id: 'bd', name: 'Treasury bonds', detail: '24% · 4.1% yield', value: '$59,565.68' },
    { id: 'cs', name: 'Cash reserve', detail: '14% · instant access', value: '$34,730.57' }
  ];

  let period = $state<Period>('1D');
</script>

<Card title="Portfolio" subtitle="All accounts · USD" level={3}>
  {#snippet append()}<Chip color="up" size="sm">+2.4% today</Chip>{/snippet}
  <p class="total">$248,190<span>.35</span></p>
  <SegmentedControl options={periods} bind:value={period} size="sm" aria-label="Period" />
  <List density="compact">
    {#each holdings as item (item.id)}
      <ListItem title={item.name} subtitle={item.detail}>
        {#snippet prepend()}<Avatar size="sm">{item.id.toUpperCase()}</Avatar>{/snippet}
        {#snippet append()}<span class="value">{item.value}</span>{/snippet}
      </ListItem>
    {/each}
  </List>
</Card>

<style>
  .total {
    margin: 0;
    font: var(--sv-weight-display) var(--sv-text-headline) / 1 var(--sv-font-display);
    letter-spacing: var(--sv-tracking-display);
    font-variant-numeric: tabular-nums;
  }

  .total span,
  .value {
    color: var(--sv-color-text-muted);
    font-variant-numeric: tabular-nums;
  }
</style>

Portfolio

All accounts · USD
+2.4% today

$248,190.35

  • World equity 62% · index fund
    $153,894.10
  • Treasury bonds 24% · 4.1% yield
    $59,565.68
  • Cash reserve 14% · instant access
    $34,730.57

A scripted replay: no model runs in your browser. The preview is the real component rendering the code beside it.

Built for coding agents

Find it, get it right, fix it

Agents do not remember your library, cannot see the screen, and learn by running and fixing. Sveltier is designed around all three, and the same choices help every developer.

Finds the right information

Every props table, llms.txt and llms-full.txt is generated from the TypeScript types, and the typed sources ship in the package. An agent reads the API of the version it installed, not a guess from its training data.

### Button
| Prop | Type | Default |
| --- | --- | --- |
| `variant` | `'elevated' \| 'flat' \| 'tonal' \| 'outlined' \| 'text' \| 'plain'` | `'flat'` |
					| `size` | `'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` |
					| `density` | `'compact' \| 'default' \| 'comfortable'` | `'default'` |
					| `color` | `Color` | `'primary'` |
					| `rounded` | `boolean \| 'none' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | `true` |
					

Gets it right the first time

variant, size, density, color and rounded mean the same thing on every component, as literal types: a value that does not exist is a type error that lists the ones that do.

Chip
Alert
<Button variant="primary">
Type '"primary"' is not assignable to type '"text" | "flat" | "elevated" | "tonal" | "outlined" | "plain" | undefined'.

Fixes itself when wrong

Every error has a stable code, says what happened and what to do, and links to its entry in the docs. The agent reads it once and corrects the next attempt.

[sveltier SV4001] Chip: a closable chip cannot also be a button or a link, since its close button would sit inside it. Put the action in a Button next to the chip. https://sveltier.com/errors#SV4001
<Chip closable>Filters</Chip>
<Button onclick={open}>Edit filters</Button>

Accessible without being asked

Roles, focus and keys follow the WAI-ARIA Authoring Practices, tested in Chromium, Firefox and WebKit. The agent never has to remember them. Try the tabs:

← → move between tabs, and the selection follows focus.

Try it

Run the replay with your own agent

Paste this into Claude Code, Cursor or any coding agent. It points the agent at llms-full.txt: setup, conventions, every component's props and every error code, generated from the same types your editor checks.

Prompt

Read ./llms-full.txt first. Then build a portfolio card in Svelte 5 with Sveltier: the total value, today's change, a period switcher and the top holdings. Use Card, Chip, SegmentedControl and List, and only the shared props (variant, size, density, color, rounded) for styling.

Right by construction

The design rules are built in

An agent picks components and props. Sveltier decides the spacing, type, sizes, motion and contrast, from the golden ratio and WCAG, so what it builds is consistent without being told how. Every theme is tested for contrast, so generated UI cannot ship unreadable text. Every value below is read from the live tokens.

Spacing: Fibonacci

Each step is about φ (1.618) times the last, so the steps look evenly spaced.

Type: powers of φ

Body text at 16px; every other size is a power of the golden ratio.

  • Ag label · φ^-¾
  • Ag xs · φ^-½
  • Ag sm · φ^-¼
  • Ag md · 1
  • Ag lg · φ^¼
  • Ag xl · φ^½
  • Ag title · φ
  • Ag headline · φ^1.25–1.75
  • Ag display · φ²–φ³

Controls: φ to φ³

Control heights climb by half powers of φ, from 26 to 68 pixels.

φ
φ^1.5
φ²
φ^2.5
φ³

Motion: Fibonacci milliseconds

Fast, normal and slow in each pack. Reduced motion takes them to 0.01ms.

PackFastNormalSlow
Monolith144ms233ms377ms
Heritage233ms377ms610ms
Aurora144ms233ms377ms
Maison233ms377ms610ms
Milano144ms233ms377ms

Contrast: WCAG, measured live

Computed now from the active theme. Switch the theme in the bar above and watch them change.

PairRatioNeeds
Aa Text on background16.97:14.5:1 ✓
Aa Muted text on surface8.46:14.5:1 ✓
Aa Subtle text on background5.28:14.5:1 ✓
Aa Control border on background3.49:13:1 ✓

Small by design

Zero dependencies. A budget on every entry.

Each component's own JavaScript and CSS, gzipped, as CI enforces it: a change that grows past its budget fails the build. Everything together stays under 32 KB.

Size budget per component, gzip
EntryBudgetBar
Portal0.85 KB
Button2.1 KB
Alert2 KB
Avatar1.2 KB
Badge1.4 KB
ButtonGroup1 KB
Card1.5 KB
Chip2.3 KB
Divider0.6 KB
Field2.55 KB
Form1.1 KB
Icon1 KB
List and ListItem2 KB
ProgressLinear1.3 KB
ProgressCircular1.5 KB
SegmentedControl2.4 KB
Skeleton1.2 KB
Tabs2.4 KB
NativeSelect1.8 KB
NumberField3.3 KB
Textarea1.55 KB
TextField1.1 KB

Theming

Change the look, keep the code

Sveltier ships with five theme packs. Switch the pack at the root, and every component changes its type, shape, colour and motion, while the code your agent wrote stays the same.

Portfolio

All accounts · USD
+2.4% today

$248,190.35

  • World equity 62% · index fund
    $153,894.10
  • Treasury bonds 24% · 4.1% yield
    $59,565.68
  • Cash reserve 14% · instant access
    $34,730.57

Build it with us

Sveltier is in alpha and built in the open. Tell us which components your agents reach for first, where they still get it wrong, and what would help them get it right.