codegen
Code generation utilities for json-render. Use when generating code from UI specs, building custom code exporters, traversing specs, or serializing props for…
Pre-built custom directives for json-render — formatting, math, string manipulation, and i18n. Use when working with @json-render/directives, defining custom directives with defineDirective, or adding $format, $math, $concat, $count, $truncate, $pluralize, $join, or $t to specs.
$ npx -y skills add vercel-labs/json-render --skill directives --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/directivesContext preview
The summary Claude sees to decide when to auto-load this skill.
Pre-built custom directives for json-render — formatting, math, string manipulation, and i18n. Use when working with @json-render/directives, defining custom directives with defineDirective, or adding $format, $math, $concat, $count, $truncate, $pluralize, $join, or $t to specs.
name: directives description: Pre-built custom directives for json-render — formatting, math, string manipulation, and i18n. Use when working with @json-render/directives, defining custom directives with defineDirective, or adding $format, $math, $concat, $count, $truncate, $pluralize, $join, or $t to specs.
Pre-built custom directives for `@json-render/core`. Drop them into your catalog and renderer to add formatting, math, string manipulation, and i18n.
import { standardDirectives } from '@json-render/directives';
// Wire into prompt generation
const prompt = catalog.prompt({ directives: standardDirectives });
// Wire into the renderer (React example)
import { JSONUIProvider, Renderer } from '@json-render/react';
<JSONUIProvider registry={registry} directives={standardDirectives}>
<Renderer spec={spec} registry={registry} />
</JSONUIProvider>To add factory directives like `createI18nDirective`, spread the array:
import { standardDirectives, createI18nDirective } from '@json-render/directives';
const directives = [...standardDirectives, createI18nDirective(config)];Use `defineDirective` from `@json-render/core`:
import { defineDirective, resolvePropValue } from '@json-render/core';
import { z } from 'zod';
const doubleDirective = defineDirective({
name: '$double',
description: 'Double a numeric value.',
schema: z.object({
$double: z.unknown(),
}),
resolve(value, ctx) {
const resolved = resolvePropValue(value.$double, ctx);
return (resolved as number) * 2;
},
});Rules:
Formats values using `Intl` formatters. Supports `date`, `currency`, `number`, and `percent`.
{ "$format": "currency", "value": { "$state": "/cart/total" }, "currency": "USD" }
{ "$format": "date", "value": { "$state": "/user/createdAt" } }
{ "$format": "number", "value": 1234567, "notation": "compact" }
{ "$format": "percent", "value": 0.75 }
{ "$format": "date", "value": { "$state": "/post/createdAt" }, "style": "relative" }Fields: `$format` (date | currency | number | percent), `value` (any expression), `locale?` (string), `currency?` (string, default "USD"), `notation?` (string), `style?` ("relative" for relative dates), `options?` (extra Intl options).
{ "$math": "add", "a": { "$state": "/subtotal" }, "b": { "$state": "/tax" } }
{ "$math": "round", "a": 3.7 }Operations: `add`, `subtract`, `multiply`, `divide`, `mod`, `min`, `max`, `round`, `floor`, `ceil`, `abs`. Unary ops (`round`, `floor`, `ceil`, `abs`) only use `a`. Division by zero returns `0`.
Fields: `$math` (operation enum), `a?` (first operand, default 0), `b?` (second operand, default 0).
{ "$concat": [{ "$state": "/user/firstName" }, " ", { "$state": "/user/lastName" }] }Fields: `$concat` (array of values to resolve and join into a string).
{ "$count": { "$state": "/cart/items" } }Returns `.length` of arrays or strings, `0` for other types.
Fields: `$count` (value to count).
{ "$truncate": { "$state": "/post/body" }, "length": 140, "suffix": "..." }Fields: `$truncate` (value to truncate), `length?` (max chars, default 100), `suffix?` (string, default "...").
{ "$pluralize": { "$state": "/cart/itemCount" }, "one": "item", "other": "items", "zero": "no items" }Output: `"3 items"`, `"1 item"`, or `"no items"`.
Fields: `$pluralize` (count value), `one` (singular label), `other` (plural label), `zero?` (zero label).
{ "$join": { "$state": "/tags" }, "separator": ", " }Fields: `$join` (array to join), `separator?` (string, default ", ").
import { createI18nDirective } from '@json-render/directives';
const tDirective = createI18nDirective({
locale: 'en',
messages: {
en: { "greeting": "Hello, {{name}}!", "checkout.submit": "Place Order" },
es: { "greeting": "Hola, {{name}}!", "checkout.submit": "Realizar Pedido" },
},
fallbackLocale: 'en',
});Usage in specs:
{ "$t": "checkout.submit" }
{ "$t": "greeting", "params": { "name": { "$state": "/user/name" } } }Fields: `$t` (translation key), `params?` (interpolation parameters, values accept expressions).
Config: `locale` (current locale), `messages` (Record<locale, Record<key, string>>), `fallbackLocale?` (fallback when key missing).
Directives compose naturally — each resolver calls `resolvePropValue` on its inputs, so directives can wrap other directives or built-in expressions:
{
"$format": "currency",
"value": { "$math": "multiply", "a": { "$state": "/price" }, "b": { "$state": "/qty" } },
"currency": "USD"
}Resolves inside-out: `$state` reads from state, `$math` multiplies, `$format` formats as currency.
All four renderers (React, Vue, Svelte, Solid) accept `directives` on their provider and `createRenderer` output:
// Provider pattern
<JSONUIProvider registry={registry} directives={directives}>
<Renderer spec={spec} registry={registry} />
</JSONUIProvider>
// createRenderer pattern
const MyRenderer = createRenderer(catalog, components);
<MyRenderer spec={spec} directives={directives} />For prompt generation, pass the same array:
const prompt = catalog.prompt({ directives });| Expo
The Generative UI framework. Generate dynamic, personalized UIs from prompts without sacrificing reliability. Predefined components and actions for safe, predictable output.
Repo: vercel-labs/json-render
Code generation utilities for json-render. Use when generating code from UI specs, building custom code exporters, traversing specs, or serializing props for…
Core package for defining schemas, catalogs, and AI prompt generation for json-render. Use when working with @json-render/core, defining schemas, creating…
Drop-in inspector panel for any json-render app. Use when the user wants to debug a generative UI, inspect the spec tree, edit state at runtime, see dispatched…
Image renderer for json-render that turns JSON specs into SVG and PNG images via Satori. Use when working with @json-render/image, generating OG images from…
Ink terminal renderer for json-render that turns JSON specs into interactive terminal UIs. Use when working with @json-render/ink, building terminal UIs from…
Jotai adapter for json-render's StateStore interface. Use when integrating json-render with Jotai for state management via @json-render/jotai.