json-render-core
Provides core JSON rendering functionalities, including Schema definition, directory creation, and canonical stream processing, for building dynamic content and components.
npx skills add https://github.com/vercel-labs/json-render --skill json-render-coreBefore / After Comparison
1 组Previously, the JSON rendering core functionality often faced performance bottlenecks when handling complex Schema definitions and large-scale directory creation. Standardized workflow processing also lacked flexibility, leading to a lengthy and error-prone process for building dynamic content and components, resulting in low development efficiency.
With the introduction of optimized JSON rendering core functionality, Schema definition and directory creation have become significantly more efficient. Standardized workflow processing has also seen substantial improvements, enabling rapid construction of dynamic content and components, greatly enhancing development efficiency and system responsiveness.
json-render-core
@json-render/core
Core package for schema definition, catalog creation, and spec streaming.
Key Concepts
-
Schema: Defines the structure of specs and catalogs (use
defineSchema) -
Catalog: Maps component/action names to their definitions (use
defineCatalog) -
Spec: JSON output from AI that conforms to the schema
-
SpecStream: JSONL streaming format for progressive spec building
Defining a Schema
import { defineSchema } from "@json-render/core";
export const schema = defineSchema((s) => ({
spec: s.object({
// Define spec structure
}),
catalog: s.object({
components: s.map({
props: s.zod(),
description: s.string(),
}),
}),
}), {
promptTemplate: myPromptTemplate, // Optional custom AI prompt
});
Creating a Catalog
import { defineCatalog } from "@json-render/core";
import { schema } from "./schema";
import { z } from "zod";
export const catalog = defineCatalog(schema, {
components: {
Button: {
props: z.object({
label: z.string(),
variant: z.enum(["primary", "secondary"]).nullable(),
}),
description: "Clickable button component",
},
},
});
Generating AI Prompts
const systemPrompt = catalog.prompt(); // Uses schema's promptTemplate
const systemPrompt = catalog.prompt({ customRules: ["Rule 1", "Rule 2"] });
SpecStream Utilities
For streaming AI responses (JSONL patches):
import { createSpecStreamCompiler } from "@json-render/core";
const compiler = createSpecStreamCompiler<MySpec>();
// Process streaming chunks
const { result, newPatches } = compiler.push(chunk);
// Get final result
const finalSpec = compiler.getResult();
Dynamic Prop Expressions
Any prop value can be a dynamic expression resolved at render time:
-
{ "$state": "/state/key" }- reads a value from the state model (one-way read) -
{ "$bindState": "/path" }- two-way binding: reads from state and enables write-back. Use on the natural value prop (value, checked, pressed, etc.) of form components. -
{ "$bindItem": "field" }- two-way binding to a repeat item field. Use inside repeat scopes. -
{ "$cond": <condition>, "$then": <value>, "$else": <value> }- evaluates a visibility condition and picks a branch -
{ "$template": "Hello, ${/user/name}!" }- interpolates${/path}references with state values -
{ "$computed": "fnName", "args": { "key": <expression> } }- calls a registered function with resolved args
$cond uses the same syntax as visibility conditions ($state, eq, neq, not, arrays for AND). $then and $else can themselves be expressions (recursive).
Components do not use a statePath prop for two-way binding. Instead, use { "$bindState": "/path" } on the natural value prop (e.g. value, checked, pressed).
{
"color": {
"$cond": { "$state": "/activeTab", "eq": "home" },
"$then": "#007AFF",
"$else": "#8E8E93"
},
"label": { "$template": "Welcome, ${/user/name}!" },
"fullName": {
"$computed": "fullName",
"args": {
"first": { "$state": "/form/firstName" },
"last": { "$state": "/form/lastName" }
}
}
}
import { resolvePropValue, resolveElementProps } from "@json-render/core";
const resolved = resolveElementProps(element.props, { stateModel: myState });
State Watchers
Elements can declare a watch field (top-level, sibling of type/props/children) to trigger actions when state values change:
{
"type": "Select",
"props": { "value": { "$bindState": "/form/country" }, "options": ["US", "Canada"] },
"watch": {
"/form/country": { "action": "loadCities", "params": { "country": { "$state": "/form/country" } } }
},
"children": []
}
Watchers only fire on value changes, not on initial render.
Validation
Built-in validation functions: required, email, url, numeric, minLength, maxLength, min, max, pattern, matches, equalTo, lessThan, greaterThan, requiredIf.
Cross-field validation uses $state expressions in args:
import { check } from "@json-render/core";
check.required("Field is required");
check.matches("/form/password", "Passwords must match");
check.lessThan("/form/endDate", "Must be before end date");
check.greaterThan("/form/startDate", "Must be after start date");
check.requiredIf("/form/enableNotifications", "Required when enabled");
User Prompt Builder
Build structured user prompts with optional spec refinement and state context:
import { buildUserPrompt } from "@json-render/core";
// Fresh generation
buildUserPrompt({ prompt: "create a todo app" });
// Refinement (patch-only mode)
buildUserPrompt({ prompt: "add a toggle", currentSpec: spec });
// With runtime state
buildUserPrompt({ prompt: "show data", state: { todos: [] } });
Spec Validation
Validate spec structure and auto-fix common issues:
import { validateSpec, autoFixSpec } from "@json-render/core";
const { valid, issues } = validateSpec(spec);
const fixed = autoFixSpec(spec);
Visibility Conditions
Control element visibility with state-based conditions. VisibilityContext is { stateModel: StateModel }.
import { visibility } from "@json-render/core";
// Syntax
{ "$state": "/path" } // truthiness
{ "$state": "/path", "not": true } // falsy
{ "$state": "/path", "eq": value } // equality
[ cond1, cond2 ] // implicit AND
// Helpers
visibility.when("/path") // { $state: "/path" }
visibility.unless("/path") // { $state: "/path", not: true }
visibility.eq("/path", val) // { $state: "/path", eq: val }
visibility.and(cond1, cond2) // { $and: [cond1, cond2] }
visibility.or(cond1, cond2) // { $or: [cond1, cond2] }
visibility.always // true
visibility.never // false
Built-in Actions in Schema
Schemas can declare builtInActions -- actions that are always available at runtime and auto-injected into prompts:
const schema = defineSchema(builder, {
builtInActions: [
{ name: "setState", description: "Update a value in the state model" },
],
});
These appear in prompts as [built-in] and don't require handlers in defineRegistry.
StateStore
The StateStore interface allows external state management libraries (Redux, Zustand, XState, etc.) to be plugged into json-render renderers. The createStateStore factory creates a simple in-memory implementation:
import { createStateStore, type StateStore } from "@json-render/core";
const store = createStateStore({ count: 0 });
store.get("/count"); // 0
store.set("/count", 1); // updates and notifies subscribers
store.update({ "/a": 1, "/b": 2 }); // batch update
store.subscribe(() => {
console.log(store.getSnapshot()); // { count: 1 }
});
The StateStore interface: get(path), set(path, value), update(updates), getSnapshot(), subscribe(listener).
Key Exports
Export Purpose
defineSchema
Create a new schema
defineCatalog
Create a catalog from schema
createStateStore
Create a framework-agnostic in-memory StateStore
resolvePropValue
Resolve a single prop expression against data
resolveElementProps
Resolve all prop expressions in an element
buildUserPrompt
Build user prompts with refinement and state context
validateSpec
Validate spec structure
autoFixSpec
Auto-fix common spec issues
createSpecStreamCompiler
Stream JSONL patches into spec
createJsonRenderTransform
TransformStream separating text from JSONL in mixed streams
parseSpecStreamLine
Parse single JSONL line
applySpecStreamPatch
Apply patch to object
StateStore
Interface for plugging in external state management
ComputedFunction
Function signature for $computed expressions
check
TypeScript helpers for creating validation checks
BuiltInAction
Type for built-in action definitions (name + description)
ActionBinding
Action binding type (includes preventDefault field)
Weekly Installs340Repositoryvercel-labs/json-renderGitHub Stars12.7KFirst SeenFeb 6, 2026Security AuditsGen Agent Trust HubPassSocketPassSnykPassInstalled oncodex316opencode315gemini-cli311github-copilot309amp294kimi-cli293
User Reviews (0)
Write a Review
No reviews yet
Statistics
User Rating
Rate this Skill