vue

vercel-labs/json-render · updated Apr 8, 2026

$npx skills add https://github.com/vercel-labs/json-render --skill vue
0 commentsdiscussion
summary

Vue 3 renderer that converts JSON specs into Vue component trees with data binding, visibility, and actions.

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

Discussion

Product Hunt–style comments (not star reviews)
  • No comments yet — start the thread.
general reviews

Ratings

4.771 reviews
  • James Bansal· Dec 28, 2024

    Useful defaults in vue — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.

  • Chaitanya Patil· Dec 24, 2024

    Solid pick for teams standardizing on skills: vue is focused, and the summary matches what you get after install.

  • Mia Torres· Dec 20, 2024

    We added vue from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.

  • Lucas Sanchez· Dec 16, 2024

    vue is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.

  • Soo Wang· Dec 16, 2024

    I recommend vue for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.

  • Lucas Rao· Dec 12, 2024

    Keeps context tight: vue is the kind of skill you can hand to a new teammate without a long onboarding doc.

  • Soo Robinson· Dec 12, 2024

    vue is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.

  • Arya Huang· Nov 23, 2024

    Useful defaults in vue — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.

  • Piyush G· Nov 15, 2024

    We added vue from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.

  • Rahul Santra· Nov 11, 2024

    I recommend vue for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.

showing 1-10 of 71

1 / 8