codegen
Code generation utilities for json-render. Use when generating code from UI specs, building custom code exporters, traversing…
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.
Claude Code
$ npx -y skills add vercel-labs/json-render --skill vue --agent claude-code
Codex
$ npx skills add vercel-labs/json-render --skill vue -a codex -y
Cursor
$ npx skills add vercel-labs/json-render --skill vue -a cursor -y
Gemini CLI
$ npx skills add vercel-labs/json-render --skill vue -a gemini-cli -y
GitHub Copilot
$ npx skills add vercel-labs/json-render --skill vue -a github-copilot -y
OpenCode
$ npx skills add vercel-labs/json-render --skill vue -a opencode -y
Windsurf
$ npx skills add vercel-labs/json-render --skill vue -a windsurf -y
name: vue description: 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.
Vue 3 renderer that converts JSON specs into Vue component trees with data binding, visibility, and actions.
npm install @json-render/vue @json-render/core zod
Peer dependencies: `vue ^3.5.0` and `zod ^4.0.0`.
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() }),
slots: ["default"],
description: "A card container",
},
Layout: {
props: z.object({}),
slots: ["default", "header", "footer"],
description: "Layout with named content regions",
},
Button: {
props: z.object({ label: z.string(), action: z.string() }),
description: "A clickable button",
},
},
actions: {},
});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,
]),
Layout: ({ slots }) =>
h("div", null, [
h("header", null, slots.header?.()),
h("main", null, slots.default?.()),
h("footer", null, slots.footer?.()),
]),
Button: ({ props, emit }) =>
h("button", { onClick: () => emit("press") }, props.label),
},
});Use `children` for the `"default"` slot. Use the element's top-level `slots` object for other slot names declared by the catalog:
{
"type": "Layout",
"props": {},
"children": ["main"],
"slots": {
"header": ["heading"],
"footer": ["actions"]
}
}Registry components receive Vue-native slot functions. Render them with `slots.header?.()`, `slots.footer?.()`, and so on. `slots.default?.()` renders the spec's `children`; the `children` context field is a convenience alias for that rendered result. In the JSON spec, keep default content in `children` rather than adding a `default` entry to `slots`.
<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>| Provider | Purpose | |----------|---------| | `StateProvider` | Share state across components (JSON Pointer paths). Accepts `initialState` or `store` for controlled mode. | | `ActionProvider` | Handle actions dispatched via the event system | | `VisibilityProvider` | Enable conditional rendering based on state | | `ValidationProvider` | Form field validation |
| Composable | Purpose | |------------|---------| | `useStateStore()` | Access state context (`state` as `ShallowRef`, `get`, `set`, `update`) | | `useStateValue(path)` | Get single value from state | | `useIsVisible(condition)` | Check if a visibility condition is met | | `useActions()` | Access action context | | `useAction(binding)` | Get a single action dispatch function | | `useFieldValidation(path, config)` | Field validation state | | `useBoundProp(propValue, bindingPath)` | Two-way binding for `$bindState`/`$bindItem` |
Note: `useStateStore().state` returns a `ShallowRef<StateModel>` — use `state.value` to access.
Nested lists can set `repeat.statePath` to `{ "$item": "field" }` inside an enclosing repeat.
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>
Props support `$state`, `$bindState`, `$cond`, `$template`, `$computed`. Use `{ "$bindState": "/path" }` on the natural value prop for two-way binding.
{ "$state": "/user/isAdmin" }
{ "$state": "/status", "eq": "active" }
{ "$state": "/maintenance", "not": true }
[ cond1, cond2 ] // implicit AND`setState`, `pushState`, `removeState`, and `validateForm` are built into the Vue schema and handled by `ActionProvider`:
{
"action": "setState",
"params": { "statePath": "/activeTab", "value": "settings" }
}Components use `emit(event)` to fire events, or `on(event)` for metadata (`shouldPreventDefault`, `bound`).
`useUIStream` and `useChatUI` return Vue Refs for streaming specs from an API.
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]);| Export | Purpose | |--------|---------| | `defineRegistry` | Create a type-safe component registry from a catalog | | `Renderer` | Render a spec using a registry | | `schema` | Element tree schema (from `@json-render/vue/schema`) | | `StateProvider`, `ActionProvider`, `VisibilityProvider`, `ValidationPro
The Generative UI framework. Generate dynamic, personalized UIs from prompts without sacrificing reliability. Predefined components and actions for safe, predictable output.
Code generation utilities for json-render. Use when generating code from UI specs, building custom code exporters, traversing…
Core package for defining schemas, catalogs, and AI prompt generation for json-render. Use when working with @json-render/core,…
React adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot…
SolidJS adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot…
Svelte 5 adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot…
Vue adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot…
Migrates React projects and components from Radix UI to Base UI. Use when asked to migrate from radix, move to base-ui, convert…
tasteskill v2, the anti-slop frontend skill. Art direction for websites, distilled from a study of 247 curated gallery sites (One…