
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.
SKILL.md
@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 |
|---|---|
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 |
Composables
| 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.
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 |
|---|---|
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, ValidationProvider | Context providers |
useStateStore, useStateValue, useBoundProp | State composables |
useActions, useAction | Action composables |
useFieldValidation, useIsVisible | Validation and visibility |
useUIStream, useChatUI | Streaming composables |
createStateStore | Create in-memory StateStore |
BaseComponentProps | Catalog-agnostic component props type |
More skills from the json-render repository
View all 25 skillscodegen
generate code from UI specifications
Jul 17Code GenerationEngineeringJSONdevtools
inspect and debug generative UI components
Jul 17DebuggingFrontendUI Componentsdirectives
apply custom directives to JSON specs
Jul 17AutomationFrontendi18nJSONimage
generate images from JSON specifications
Jul 17ImagesJSONSatoriSVGink
render JSON specs as terminal UIs
Jul 17CLIJSONUI Componentsjotai
manage state with Jotai
Jul 17FrontendReactState Management
More from Vercel Labs
View publisheragent-browser
automate browser interactions for AI agents
agent-browser
Jul 20AgentsAutomationBrowser Automationagentcore
run browser automation on AWS Bedrock
agent-browser
Jul 17AutomationAWSBrowser Automationcore
navigate and interact with web pages
agent-browser
Jul 26AgentsBrowser AutomationNavigationderive-client
reverse engineer internal APIs from browser traffic
agent-browser
Jul 20API DevelopmentAutomationBrowser AutomationWeb Scrapingdogfood
perform exploratory testing on web applications
agent-browser
Jul 17Browser AutomationDebuggingQATestingelectron
automate Electron desktop applications
agent-browser
Jul 17AgentsBrowser AutomationDesktop