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…

INSTALLATION
npx skills add https://github.com/vercel-labs/json-render --skill vue
Run in your project or agent environment. Adjust flags if your CLI version differs.

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

BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card