
Directives
Wire json-render standard and custom directives ($format, $math, i18n) into catalog prompts and React renderers for AI-generated UI specs.
Overview
directives is an agent skill for the Build phase that teaches how to add and wire @json-render/directives—including standard and custom defineDirective handlers—for AI-generated UI specs.
Install
npx skills add https://github.com/vercel-labs/json-render --skill directivesWhat is this skill?
- Ships standardDirectives for format, math, string ops, and i18n via @json-render/directives
- Documents wiring into catalog.prompt and JSONUIProvider with directives prop
- Covers createI18nDirective factory spread alongside standardDirectives
- Shows defineDirective pattern with zod schema and resolvePropValue
Adoption & trust: 165 installs on skills.sh; 15k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your json-render specs reference $format or i18n directives but prompts and the React renderer disagree on which directives exist or how they validate.
Who is it for?
Indie devs building AI-driven dashboards or forms with @json-render/react who need directive parity between generation and render.
Skip if: Projects not using json-render, or teams that only need static React components without spec-level directives.
When should I use this skill?
Working with @json-render/directives, defineDirective, or adding $format, $math, $concat, $count, $truncate, $pluralize, $join, or $t to specs.
What do I get? / Deliverables
After applying the skill, standardDirectives and optional i18n factories are registered in both prompt catalog and JSONUIProvider so specs resolve predictably.
- Directive array wired to catalog.prompt and renderer
- Custom defineDirective implementation with zod schema
Recommended Skills
Journey fit
Directive wiring is core frontend build work when you implement json-render catalogs and renderers. Frontend subphase because the skill covers @json-render/directives, JSONUIProvider, Renderer, and defineDirective schemas for UI specs.
How it compares
Skill package for json-render directive APIs, not a separate UI component library or MCP server.
Common Questions / FAQ
Who is directives for?
Solo builders and small front-end teams using Vercel json-render who want agents to correctly implement directive catalogs.
When should I use directives?
During Build when integrating @json-render/directives, defining custom defineDirective helpers, or fixing $format/$t resolution in specs.
Is directives safe to install?
It is documentation and code patterns only with no runtime secrets; still review the Security Audits panel on this page before trusting third-party skill sources.
SKILL.md
READMESKILL.md - Directives
# @json-render/directives Pre-built custom directives for `@json-render/core`. Drop them into your catalog and renderer to add formatting, math, string manipulation, and i18n. ## Quick Start ```typescript 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: ```typescript import { standardDirectives, createI18nDirective } from '@json-render/directives'; const directives = [...standardDirectives, createI18nDirective(config)]; ``` ## Defining Custom Directives Use `defineDirective` from `@json-render/core`: ```typescript 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: - Name must start with `$` - Name must not conflict with built-in keys (`$state`, `$cond`, `$computed`, `$template`, `$item`, `$index`, `$bindState`, `$bindItem`) - Resolvers should call `resolvePropValue` on sub-values to support composition ## Built-in Directives ### `$format` — Locale-aware value formatting Formats values using `Intl` formatters. Supports `date`, `currency`, `number`, and `percent`. ```json { "$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` — Arithmetic operations ```json { "$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` — String concatenation ```json { "$concat": [{ "$state": "/user/firstName" }, " ", { "$state": "/user/lastName" }] } ``` Fields: `$concat` (array of values to resolve and join into a string). ### `$count` — Array/string length ```json { "$count": { "$state": "/cart/items" } } ``` Returns `.length` of arrays or strings, `0` for other types. Fields: `$count` (value to count). ### `$truncate` — Text truncation ```json { "$truncate": { "$state": "/post/body" }, "length": 140, "suffix": "..." } ``` Fields: `$truncate` (value to truncate), `length?` (max chars, default 100), `suffix?` (string, default "..."). ### `$pluralize` — Singular/plural forms ```json { "$pluralize": { "$state": "/cart/itemCount" }, "one": "item", "other": "items", "zero": "no items" } ``` Output: `"3 items"`, `"1 item"`, or `"no items"`. Fields: `$pluralize` (count val