description:Core package for defining schemas, catalogs, and AI prompt generation for json-render. Use when working with @json-render/core, defining schemas, creating catalogs, or building JSON specs for UI/video generation.
---
# @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
```typescript
import{defineSchema}from"@json-render/core";
exportconstschema=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
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`).
Schemas can declare `builtInActions` -- actions that are always available at runtime and auto-injected into prompts:
```typescript
constschema=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: