Json-render vue
Vue 3 renderer for json-render. Use when building Vue UIs from JSON specs, working with @json-render/vue, defining Vue component registries, or rendering AI-generated specs in Vue.
install
source · Clone the upstream repo
git clone https://github.com/vercel-labs/json-render
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/vercel-labs/json-render "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/vue" ~/.claude/skills/vercel-labs-json-render-vue && rm -rf "$T"
manifest:
skills/vue/SKILL.mdsource content
@json-render/vue
Vue 3 renderer that converts JSON specs into Vue component trees with data binding, visibility, and actions.
Installation
npm install @json-render/vue @json-render/core zod
Peer dependencies:
vue ^3.5.0 and zod ^4.0.0.
Quick Start
Create a Catalog
import { defineCatalog } from "@json-render/core"; import { schema } from "@json-render/vue/schema"; import { z } from "zod"; export const catalog = defineCatalog(schema, { components: { Card: { props: z.object({ title: z.string(), description: z.string().nullable() }), description: "A card container", }, Button: { props: z.object({ label: z.string(), action: z.string() }), description: "A clickable button", }, }, actions: {}, });
Define Registry with h() Render Functions
import { h } from "vue"; import { defineRegistry } from "@json-render/vue"; import { catalog } from "./catalog"; export const { registry } = defineRegistry(catalog, { components: { Card: ({ props, children }) => h("div", { class: "card" }, [ h("h3", null, props.title), props.description ? h("p", null, props.description) : null, children, ]), Button: ({ props, emit }) => h("button", { onClick: () => emit("press") }, props.label), }, });
Render Specs
<script setup lang="ts"> import { StateProvider, ActionProvider, Renderer } from "@json-render/vue"; import { registry } from "./registry"; const spec = { root: "card-1", elements: { /* ... */ } }; </script> <template> <StateProvider :initial-state="{ form: { name: '' } }"> <ActionProvider :handlers="{ submit: handleSubmit }"> <Renderer :spec="spec" :registry="registry" /> </ActionProvider> </StateProvider> </template>
Providers
| Provider | Purpose |
|---|---|
| Share state across components (JSON Pointer paths). Accepts or for controlled mode. |
| Handle actions dispatched via the event system |
| Enable conditional rendering based on state |
| Form field validation |
Composables
| Composable | Purpose |
|---|---|
| Access state context ( as , , , ) |
| Get single value from state |
| Check if a visibility condition is met |
| Access action context |
| Get a single action dispatch function |
| Field validation state |
| Two-way binding for / |
Note:
useStateStore().state returns a ShallowRef<StateModel> — use state.value to access.
External Store (StateStore)
Pass a
StateStore to StateProvider to wire json-render to Pinia, VueUse, or any state management:
import { createStateStore, type StateStore } from "@json-render/vue"; const store = createStateStore({ count: 0 });
<StateProvider :store="store"> <Renderer :spec="spec" :registry="registry" /> </StateProvider>
Dynamic Prop Expressions
Props support
$state, $bindState, $cond, $template, $computed. Use { "$bindState": "/path" } on the natural value prop for two-way binding.
Visibility Conditions
{ "$state": "/user/isAdmin" } { "$state": "/status", "eq": "active" } { "$state": "/maintenance", "not": true } [ cond1, cond2 ] // implicit AND
Built-in Actions
setState, pushState, removeState, and validateForm are built into the Vue schema and handled by ActionProvider:
{ "action": "setState", "params": { "statePath": "/activeTab", "value": "settings" } }
Event System
Components use
emit(event) to fire events, or on(event) for metadata (shouldPreventDefault, bound).
Streaming
useUIStream and useChatUI return Vue Refs for streaming specs from an API.
BaseComponentProps
For catalog-agnostic reusable components:
import type { BaseComponentProps } from "@json-render/vue"; const Card = ({ props, children }: BaseComponentProps<{ title?: string }>) => h("div", null, [props.title, children]);
Key Exports
| Export | Purpose |
|---|---|
| Create a type-safe component registry from a catalog |
| Render a spec using a registry |
| Element tree schema (from ) |
, , , | Context providers |
, , | State composables |
, | Action composables |
, | Validation and visibility |
, | Streaming composables |
| Create in-memory |
| Catalog-agnostic component props type |