Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
vercel-labs avatar

Svelte

  • 891 installs
  • 15.8k repo stars
  • Updated July 8, 2026
  • vercel-labs/json-render

Svelte 5 json-render integration: catalogs, registries, Renderer, state/actions, visibility, and streaming UI from JSON specs.

About

Documents @json-render/svelte: a Svelte 5 renderer converting JSON specs into component trees via Renderer and JsonUIProvider. Covers defineCatalog with zod props, BaseComponentProps with emit/children/bindings, defineRegistry with actions, element-tree spec format, visibility conditions, and built-in setState actions. Explains dynamic props ($state, $bindState, $cond), getBoundProp for two-way binding, context helpers, and createUIStream/createChatUI for streaming AI-generated UI. Components map spec types to Svelte files through a registry object.

  • Svelte 5 Renderer + JsonUIProvider quick start pattern
  • defineCatalog and defineRegistry with zod-validated component props
  • Element tree spec with root, children, visibility, and on action bindings
  • State, action, visibility, and validation contexts via JsonUIProvider
  • createUIStream and createChatUI for streaming AI-generated specs

Svelte by the numbers

  • 891 all-time installs (skills.sh)
  • +24 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #423 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
At a glance

svelte capabilities & compatibility

Capabilities
define svelte catalog · wire component registry · bind spec state · handle spec actions · stream ui specs
Use cases
frontend · ui design · orchestration
From the docs

What svelte says it does

Svelte 5 renderer that converts json-render specs into Svelte component trees.
SKILL.md
npx skills add https://github.com/vercel-labs/json-render --skill svelte

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs891
repo stars15.8k
Security audit3 / 3 scanners passed
Last updatedJuly 8, 2026
Repositoryvercel-labs/json-render

How do I render AI-generated JSON UI specs in Svelte 5 with state, events, and component registries?

Render json-render JSON specs into Svelte 5 component trees with catalogs, registries, state, actions, and streaming UI.

Who is it for?

Frontend developers using @json-render/svelte to build dynamic or AI-streamed UIs in Svelte 5.

Skip if: React/Vue json-render setups or backend-only JSON schema work without Svelte components.

When should I use this skill?

User works with @json-render/svelte, builds Svelte UIs from JSON, creates component catalogs, or renders AI-generated specs.

What you get

Working Svelte components, catalog, and registry that render json-render element-tree specs with actions and bindings.

  • Renderer and JsonUIProvider setup
  • Component catalog mappings
  • JSON-driven Svelte UI trees

By the numbers

  • Targets Svelte 5 with $props() and @json-render/svelte Renderer APIs

Files

SKILL.mdMarkdownGitHub ↗

@json-render/svelte

Svelte 5 renderer that converts json-render specs into Svelte component trees.

Quick Start

<script lang="ts">
  import { Renderer, JsonUIProvider } from "@json-render/svelte";
  import type { Spec } from "@json-render/svelte";
  import Card from "./components/Card.svelte";
  import Button from "./components/Button.svelte";

  interface Props {
    spec: Spec | null;
  }

  let { spec }: Props = $props();
  const registry = { Card, Button };
</script>

<JsonUIProvider>
  <Renderer {spec} {registry} />
</JsonUIProvider>

Creating a Catalog

import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/svelte";
import { z } from "zod";

export const catalog = defineCatalog(schema, {
  components: {
    Button: {
      props: z.object({
        label: z.string(),
        variant: z.enum(["primary", "secondary"]).nullable(),
      }),
      description: "Clickable button",
    },
    Card: {
      props: z.object({ title: z.string() }),
      description: "Card container with title",
    },
  },
});

Defining Components

Components should accept BaseComponentProps<TProps>:

interface BaseComponentProps<TProps> {
  props: TProps; // Resolved props for this component
  children?: Snippet; // Child elements (use {@render children()})
  emit: (event: string) => void; // Fire a named event
  bindings?: Record<string, string>; // Map of prop names to state paths (for $bindState)
  loading?: boolean; // True while spec is streaming
}
<!-- Button.svelte -->
<script lang="ts">
  import type { BaseComponentProps } from "@json-render/svelte";

  interface Props extends BaseComponentProps<{ label: string; variant?: string }> {}
  let { props, emit }: Props = $props();
</script>

<button class={props.variant} onclick={() => emit("press")}>
  {props.label}
</button>
<!-- Card.svelte -->
<script lang="ts">
  import type { Snippet } from "svelte";
  import type { BaseComponentProps } from "@json-render/svelte";

  interface Props extends BaseComponentProps<{ title: string }> {
    children?: Snippet;
  }

  let { props, children }: Props = $props();
</script>

<div class="card">
  <h2>{props.title}</h2>
  {#if children}
    {@render children()}
  {/if}
</div>

Creating a Registry

import { defineRegistry } from "@json-render/svelte";
import { catalog } from "./catalog";
import Card from "./components/Card.svelte";
import Button from "./components/Button.svelte";

const { registry, handlers, executeAction } = defineRegistry(catalog, {
  components: {
    Card,
    Button,
  },
  actions: {
    submit: async (params, setState, state) => {
      // handle action
    },
  },
});

Spec Structure (Element Tree)

The Svelte schema uses the element tree format:

{
  "root": "card1",
  "elements": {
    "card1": {
      "type": "Card",
      "props": { "title": "Hello" },
      "children": ["btn1"]
    },
    "btn1": {
      "type": "Button",
      "props": { "label": "Click me" }
    }
  }
}

Visibility Conditions

Use visible on elements to show/hide based on state:

  • { "$state": "/path" } - truthy check
  • { "$state": "/path", "eq": value } - equality check
  • { "$state": "/path", "not": true } - falsy check
  • { "$and": [cond1, cond2] } - AND conditions
  • { "$or": [cond1, cond2] } - OR conditions

Providers (via JsonUIProvider)

JsonUIProvider composes all contexts. Individual contexts:

ContextPurpose
StateContextShare state across components (JSON Pointer paths)
ActionContextHandle actions dispatched via the event system
VisibilityContextEnable conditional rendering based on state
ValidationContextForm field validation

Event System

Components use emit to fire named events. The element's on field maps events to action bindings:

<!-- Button.svelte -->
<script lang="ts">
  import type { BaseComponentProps } from "@json-render/svelte";

  interface Props extends BaseComponentProps<{ label: string }> {}

  let { props, emit }: Props = $props();
</script>

<button onclick={() => emit("press")}>{props.label}</button>
{
  "type": "Button",
  "props": { "label": "Submit" },
  "on": { "press": { "action": "submit" } }
}

Built-in Actions

The setState action is handled automatically and updates the state model:

{
  "action": "setState",
  "actionParams": { "statePath": "/activeTab", "value": "home" }
}

Other built-in actions: pushState, removeState, push, pop.

Dynamic Props and Two-Way Binding

Expression forms resolved before your component receives props:

  • {"$state": "/state/key"} - read from state
  • {"$bindState": "/form/email"} - read + write-back to state
  • {"$bindItem": "field"} - read + write-back for repeat items
  • {"$cond": <condition>, "$then": <value>, "$else": <value>} - conditional value

For writable bindings inside components, use getBoundProp:

<script lang="ts">
  import { getBoundProp } from "@json-render/svelte";
  import type { BaseComponentProps } from "@json-render/svelte";

  interface Props extends BaseComponentProps<{ value?: string }> {}
  let { props, bindings }: Props = $props();

  let value = getBoundProp<string>(
    () => props.value,
    () => bindings?.value,
  );
</script>

<input bind:value={value.current} />

Context Helpers

Preferred helpers:

  • getStateValue(path) - returns { current } (read/write)
  • getBoundProp(() => value, () => bindingPath) - returns { current } (read/write when bound)
  • isVisible(condition) - returns { current } (boolean)
  • getAction(name) - returns { current } (registered handler)

Advanced context access:

  • getStateContext()
  • getActionContext()
  • getVisibilityContext()
  • getValidationContext()
  • getOptionalValidationContext()
  • getFieldValidation(ctx, path, config?)

Streaming UI

Use createUIStream for spec streaming:

<script lang="ts">
  import { createUIStream, Renderer } from "@json-render/svelte";

  const stream = createUIStream({
    api: "/api/generate-ui",
    onComplete: (spec) => console.log("Done", spec),
  });

  async function generate() {
    await stream.send("Create a login form");
  }
</script>

<button onclick={generate} disabled={stream.isStreaming}>
  {stream.isStreaming ? "Generating..." : "Generate UI"}
</button>

{#if stream.spec}
  <Renderer spec={stream.spec} {registry} loading={stream.isStreaming} />
{/if}

Use createChatUI for chat + UI responses:

const chat = createChatUI({ api: "/api/chat-ui" });
await chat.send("Build a settings panel");

Related skills

How it compares

Pick svelte over generic Svelte skills when rendering LLM or API JSON specs through @json-render/svelte, not static component authoring.

FAQ

What is the minimal render setup?

Wrap Renderer in JsonUIProvider, pass spec and a registry mapping spec types to Svelte components like Card and Button.

How do components emit actions?

Components call emit(eventName); the spec element on field maps events to actions such as submit or setState.

Does it support streaming specs?

Yes. createUIStream and createChatUI fetch partial specs from an API and pass loading state to Renderer.

Is Svelte safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

Frontend Developmentfrontendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.