page.mdx 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758
  1. import { pageMetadata } from "@/lib/page-metadata"
  2. export const metadata = pageMetadata("docs/changelog")
  3. # Changelog
  4. Notable changes and updates to json-render.
  5. ## v0.10.0
  6. February 2026
  7. ### New: `@json-render/vue`
  8. Vue 3 renderer for json-render with full feature parity with `@json-render/react`. Data binding, visibility conditions, actions, validation, repeat scopes, streaming, and external store support.
  9. ```bash
  10. npm install @json-render/core @json-render/vue
  11. ```
  12. ```typescript
  13. import { h } from "vue";
  14. import { defineRegistry, Renderer } from "@json-render/vue";
  15. import { schema } from "@json-render/vue/schema";
  16. const { registry } = defineRegistry(catalog, {
  17. components: {
  18. Card: ({ props, children }) =>
  19. h("div", { class: "card" }, [h("h3", null, props.title), children]),
  20. Button: ({ props, emit }) =>
  21. h("button", { onClick: () => emit("press") }, props.label),
  22. },
  23. });
  24. ```
  25. Providers: `StateProvider`, `ActionProvider`, `VisibilityProvider`, `ValidationProvider`. Composables: `useStateStore`, `useStateValue`, `useActions`, `useAction`, `useIsVisible`, `useFieldValidation`, `useBoundProp`, `useUIStream`, `useChatUI`.
  26. See the [Vue API reference](/docs/api/vue) for details.
  27. ### New: `@json-render/xstate`
  28. [XState Store](https://stately.ai/docs/xstate-store) (atom) adapter for json-render's `StateStore` interface. Wire an `@xstate/store` atom as the state backend for any renderer.
  29. ```bash
  30. npm install @json-render/xstate @xstate/store
  31. ```
  32. ```typescript
  33. import { createAtom } from "@xstate/store";
  34. import { xstateStoreStateStore } from "@json-render/xstate";
  35. const atom = createAtom({ count: 0 });
  36. const store = xstateStoreStateStore({ atom });
  37. ```
  38. Requires `@xstate/store` v3+.
  39. ### New: `$computed` and `$template` Expressions
  40. Two new prop expression types for dynamic values:
  41. - **`$template`** -- interpolate state values into strings: `{ "$template": "Hello, ${/user/name}!" }`
  42. - **`$computed`** -- call registered functions: `{ "$computed": "fullName", "args": { "first": { "$state": "/form/firstName" } } }`
  43. Register functions via the `functions` prop on `JSONUIProvider` or `createRenderer`. See [Computed Values](/docs/computed-values) for details.
  44. ### New: State Watchers
  45. Elements can declare a `watch` field to trigger actions when state values change. Useful for cascading dependencies like country/city selects.
  46. ```json
  47. {
  48. "type": "Select",
  49. "props": { "value": { "$bindState": "/form/country" }, "options": ["US", "Canada"] },
  50. "watch": {
  51. "/form/country": { "action": "loadCities", "params": { "country": { "$state": "/form/country" } } }
  52. }
  53. }
  54. ```
  55. `watch` is a top-level field on elements (sibling of type/props/children), not inside props. Watchers only fire on value changes, not on initial render. See [Watchers](/docs/watchers) for details.
  56. ### New: Cross-Field Validation
  57. New built-in validation functions for cross-field comparisons:
  58. - `equalTo` -- alias for `matches` with clearer semantics
  59. - `lessThan` -- value must be less than another field
  60. - `greaterThan` -- value must be greater than another field
  61. - `requiredIf` -- required only when a condition field is truthy
  62. Validation check args now resolve through `resolvePropValue`, so `$state` expressions work consistently.
  63. ### New: `validateForm` Action
  64. Built-in action (React) that validates all registered form fields at once and writes `{ valid, errors }` to state:
  65. ```json
  66. {
  67. "on": {
  68. "press": [
  69. { "action": "validateForm", "params": { "statePath": "/formResult" } },
  70. { "action": "submitForm" }
  71. ]
  72. }
  73. }
  74. ```
  75. ### Improved: shadcn/ui Validation
  76. All form components now support `checks` and `validateOn` props:
  77. - Checkbox, Radio, Switch added validation support
  78. - `validateOn` controls timing: `"change"` (default for Select, Checkbox, Radio, Switch), `"blur"` (default for Input, Textarea), or `"submit"`
  79. ### New Examples
  80. - **Vue example** -- standalone Vue 3 app with custom components
  81. - **Vite Renderers** -- side-by-side React and Vue renderers with shared catalog
  82. ---
  83. ## v0.9.1
  84. February 2026
  85. ### Fixed: Install failure due to private dependency
  86. `@json-render/react`, `@json-render/react-pdf`, and `@json-render/react-native` v0.9.0 failed to install because `@internal/react-state` (a private workspace package) was published as a dependency. The internal package is now bundled into each renderer at build time, so it no longer needs to be resolved from npm.
  87. ---
  88. ## v0.9.0
  89. February 2026
  90. ### New: External State Store
  91. The `StateStore` interface lets you plug in your own state management (Redux, Zustand, Jotai, XState, etc.) instead of the built-in internal store. Pass a `store` prop to `StateProvider`, `JSONUIProvider`, or `createRenderer` for controlled mode.
  92. - Added `StateStore` interface and `createStateStore()` factory to `@json-render/core`
  93. - `StateProvider`, `JSONUIProvider`, and `createRenderer` now accept an optional `store` prop
  94. - When `store` is provided, it becomes the single source of truth (`initialState`/`onStateChange` are ignored)
  95. - When `store` is omitted, everything works exactly as before (fully backward compatible)
  96. - Applied across all platform packages: react, react-native, react-pdf
  97. - Store utilities (`createStoreAdapter`, `immutableSetByPath`, `flattenToPointers`) available via `@json-render/core/store-utils` for building custom adapters
  98. New adapter packages: `@json-render/redux`, `@json-render/zustand`, `@json-render/jotai`.
  99. See the [Data Binding](/docs/data-binding#external-store-controlled-mode) guide for usage.
  100. ### Changed: `onStateChange` signature updated (breaking)
  101. The `onStateChange` callback now receives a single array of changed entries instead of being called once per path. This makes batch updates via `update()` easier to handle:
  102. ```ts
  103. // Before
  104. onStateChange?: (path: string, value: unknown) => void
  105. // After
  106. onStateChange?: (changes: Array<{ path: string; value: unknown }>) => void
  107. ```
  108. The callback is only called when a `set()` or `update()` call actually changes the state. A `set()` call produces a single-element array; an `update()` call produces one array with all changed paths.
  109. ### Fixed: Server-safe schema import
  110. `@json-render/react` barrel-imports React contexts that call `createContext`, which crashes in Next.js App Router API routes (RSC runtime strips `createContext`). All docs, examples, and skills now import `schema` from `@json-render/react/schema` instead of `@json-render/react`.
  111. For combined imports, split into separate `schema` (subpath) and client API (main entry) lines:
  112. ```ts
  113. import { schema } from "@json-render/react/schema";
  114. import { defineRegistry, Renderer } from "@json-render/react";
  115. ```
  116. ### Fixed: Chaining actions
  117. Fixed an issue where chaining multiple actions on the same event (e.g. `setState` followed by a custom action) did not execute all actions. Affected `@json-render/react`, `@json-render/react-native`, and `@json-render/react-pdf`.
  118. ### Fixed: Zod array inner type resolution
  119. Fixed safely resolving the inner type for Zod arrays in schema introspection, preventing errors when catalog component props use `z.array()`.
  120. ---
  121. ## v0.8.0
  122. February 2026
  123. ### New: `@json-render/react-pdf`
  124. PDF renderer for json-render, powered by [`@react-pdf/renderer`](https://react-pdf.org/). Define catalogs and registries the same way as `@json-render/react`, but output PDF documents instead of web UI.
  125. ```bash
  126. npm install @json-render/core @json-render/react-pdf
  127. ```
  128. ```typescript
  129. import { renderToBuffer } from "@json-render/react-pdf";
  130. import type { Spec } from "@json-render/core";
  131. const spec: Spec = {
  132. root: "doc",
  133. elements: {
  134. doc: { type: "Document", props: { title: "Invoice" }, children: ["page"] },
  135. page: {
  136. type: "Page",
  137. props: { size: "A4" },
  138. children: ["heading", "table"],
  139. },
  140. heading: {
  141. type: "Heading",
  142. props: { text: "Invoice #1234", level: "h1" },
  143. children: [],
  144. },
  145. table: {
  146. type: "Table",
  147. props: {
  148. columns: [
  149. { header: "Item", width: "60%" },
  150. { header: "Price", width: "40%", align: "right" },
  151. ],
  152. rows: [
  153. ["Widget A", "$10.00"],
  154. ["Widget B", "$25.00"],
  155. ],
  156. },
  157. children: [],
  158. },
  159. },
  160. };
  161. const buffer = await renderToBuffer(spec);
  162. ```
  163. Server-side rendering APIs:
  164. - `renderToBuffer(spec)` -- render to an in-memory PDF buffer
  165. - `renderToStream(spec)` -- render to a readable stream (pipe to HTTP response)
  166. - `renderToFile(spec, path)` -- render directly to a file
  167. 15 standard components covering document structure (Document, Page), layout (View, Row, Column), content (Heading, Text, Image, Link), data (Table, List), decorative (Divider, Spacer), and page-level (PageNumber).
  168. Supports custom catalogs with `defineRegistry`, server-safe imports via `@json-render/react-pdf/server`, and full context support (state, visibility, actions, validation, repeat scopes).
  169. ---
  170. ## v0.7.0
  171. February 2026
  172. ### New: `@json-render/shadcn`
  173. Pre-built [shadcn/ui](https://ui.shadcn.com/) component library for json-render. 36 components built on Radix UI + Tailwind CSS, ready to use with `defineCatalog` and `defineRegistry`.
  174. ```bash
  175. npm install @json-render/shadcn
  176. ```
  177. ```typescript
  178. import { defineCatalog } from "@json-render/core";
  179. import { schema } from "@json-render/react/schema";
  180. import { shadcnComponentDefinitions } from "@json-render/shadcn/catalog";
  181. import { defineRegistry } from "@json-render/react";
  182. import { shadcnComponents } from "@json-render/shadcn";
  183. const catalog = defineCatalog(schema, {
  184. components: {
  185. Card: shadcnComponentDefinitions.Card,
  186. Button: shadcnComponentDefinitions.Button,
  187. Input: shadcnComponentDefinitions.Input,
  188. },
  189. actions: {},
  190. });
  191. const { registry } = defineRegistry(catalog, {
  192. components: {
  193. Card: shadcnComponents.Card,
  194. Button: shadcnComponents.Button,
  195. Input: shadcnComponents.Input,
  196. },
  197. });
  198. ```
  199. Components include: layout (Card, Stack, Grid, Separator), navigation (Tabs, Accordion, Collapsible, Pagination), overlay (Dialog, Drawer, Tooltip, Popover, DropdownMenu), content (Heading, Text, Image, Avatar, Badge, Alert, Carousel, Table), feedback (Progress, Skeleton, Spinner), and input (Button, Link, Input, Textarea, Select, Checkbox, Radio, Switch, Slider, Toggle, ToggleGroup, ButtonGroup).
  200. See the [API reference](/docs/api/shadcn) for full details.
  201. ### New: Event Handles (`on()`)
  202. Components now receive an `on(event)` function in addition to `emit(event)`. The `on()` function returns an `EventHandle` with metadata:
  203. - `emit()` -- fire the event
  204. - `shouldPreventDefault` -- whether any action binding requested `preventDefault`
  205. - `bound` -- whether any handler is bound to this event
  206. ```tsx
  207. Link: ({ props, on }) => {
  208. const click = on("click");
  209. return (
  210. <a href={props.href} onClick={(e) => {
  211. if (click.shouldPreventDefault) e.preventDefault();
  212. click.emit();
  213. }}>{props.label}</a>
  214. );
  215. },
  216. ```
  217. ### New: `BaseComponentProps`
  218. Catalog-agnostic base type for component render functions. Use when building reusable component libraries (like `@json-render/shadcn`) that are not tied to a specific catalog.
  219. ```typescript
  220. import type { BaseComponentProps } from "@json-render/react";
  221. const Card = ({ props, children }: BaseComponentProps<{ title?: string }>) => (
  222. <div>{props.title}{children}</div>
  223. );
  224. ```
  225. ### New: Built-in Actions in Schema
  226. Schemas can now declare `builtInActions` -- actions that are always available at runtime and automatically injected into prompts. The React schema declares `setState`, `pushState`, and `removeState` as built-in, so they appear in prompts without needing to be listed in catalog `actions`.
  227. ### New: `preventDefault` on `ActionBinding`
  228. Action bindings now support a `preventDefault` boolean field, allowing the LLM to request that default browser behavior (e.g. navigation on links) be prevented.
  229. ### Improved: Stream Transform Text Block Splitting
  230. `createJsonRenderTransform()` now properly splits text blocks around spec data by emitting `text-end`/`text-start` pairs. This ensures the AI SDK creates separate text parts, preserving correct interleaving of prose and UI in `message.parts`.
  231. ### Improved: `defineRegistry` Actions Requirement
  232. `defineRegistry` now conditionally requires the `actions` field only when the catalog declares actions. Catalogs with no actions (e.g. `actions: {}`) no longer need to pass an empty actions object.
  233. ---
  234. ## v0.6.0
  235. February 2026
  236. ### New: Chat Mode (Inline GenUI)
  237. > **Note:** These modes were renamed in v0.12.1 — "Generate" is now "Standalone" and "Chat" is now "Inline". The old names are accepted as deprecated aliases.
  238. json-render now supports two generation modes: **Generate** (JSONL-only, the default) and **Chat** (text + JSONL inline). Chat mode lets the AI respond conversationally with embedded UI specs, ideal for chatbots and copilot experiences.
  239. ```typescript
  240. // Generate mode (default) — AI outputs only JSONL
  241. const prompt = catalog.prompt();
  242. // Chat mode — AI outputs text + JSONL inline
  243. const chatPrompt = catalog.prompt({ mode: "chat" });
  244. ```
  245. On the server, `pipeJsonRender()` separates text from JSONL patches in a mixed stream:
  246. ```typescript
  247. import { pipeJsonRender } from "@json-render/core";
  248. import { createUIMessageStream, createUIMessageStreamResponse } from "ai";
  249. const stream = createUIMessageStream({
  250. execute: async ({ writer }) => {
  251. writer.merge(pipeJsonRender(result.toUIMessageStream()));
  252. },
  253. });
  254. return createUIMessageStreamResponse({ stream });
  255. ```
  256. On the client, `useJsonRenderMessage` extracts the spec and text from message parts:
  257. ```tsx
  258. import { useJsonRenderMessage } from "@json-render/react";
  259. function ChatMessage({ message }) {
  260. const { spec, text, hasSpec } = useJsonRenderMessage(message.parts);
  261. return (
  262. <div>
  263. {text && <Markdown>{text}</Markdown>}
  264. {hasSpec && <Renderer spec={spec} registry={registry} />}
  265. </div>
  266. );
  267. }
  268. ```
  269. ### New: AI SDK Integration
  270. First-class Vercel AI SDK support with typed data parts and stream utilities.
  271. - `SpecDataPart` type for `data-spec` stream parts (patch, flat, nested payloads)
  272. - `SPEC_DATA_PART` / `SPEC_DATA_PART_TYPE` constants for type-safe part filtering
  273. - `createJsonRenderTransform()` low-level TransformStream for custom pipelines
  274. - `createMixedStreamParser()` for parsing mixed text + JSONL streams
  275. ### New: Two-Way Binding
  276. Props can now use `$bindState` and `$bindItem` expressions for two-way data binding. The renderer resolves bindings and passes a `bindings` map to components, enabling write-back to state without custom `valuePath` props.
  277. ```json
  278. {
  279. "type": "Input",
  280. "props": { "label": "Email", "value": { "$bindState": "/form/email" } }
  281. }
  282. ```
  283. ```tsx
  284. import { useBoundProp } from "@json-render/react";
  285. Input: ({ props, bindings }) => {
  286. const [value, setValue] = useBoundProp<string>(props.value, bindings?.value);
  287. return <input value={value ?? ""} onChange={(e) => setValue(e.target.value)} />;
  288. }
  289. ```
  290. ### New: Expression-Based Props and Visibility
  291. All dynamic expressions now use structured `$state`, `$item`, and `$index` objects instead of string token rewriting. This is simpler, more explicit, and works for both props and visibility conditions.
  292. **Props:**
  293. ```json
  294. { "title": { "$state": "/user/name" } }
  295. { "label": { "$item": "title" } }
  296. { "position": { "$index": true } }
  297. ```
  298. **Visibility:**
  299. ```json
  300. { "$state": "/isAdmin" }
  301. { "$state": "/role", "eq": "admin" }
  302. [{ "$state": "/isAdmin" }, { "$state": "/feature" }]
  303. { "$or": [{ "$state": "/roleA" }, { "$state": "/roleB" }] }
  304. { "$item": "isActive" }
  305. { "$index": true, "gt": 0 }
  306. ```
  307. Comparison operators: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `not`.
  308. ### New: React Chat Hooks
  309. - `useChatUI()` — full chat hook with message history, streaming, and spec extraction
  310. - `useJsonRenderMessage()` — extract spec + text from a message's parts array
  311. - `buildSpecFromParts()` / `getTextFromParts()` — utilities for working with AI SDK message parts
  312. - `useBoundProp()` — two-way binding hook for `$bindState` / `$bindItem`
  313. ### New: Chat Example
  314. Full-featured chat example (`examples/chat`) with AI agent, tool calls (crypto, GitHub, Hacker News, weather, search), theme toggle, and streaming inline UI generation.
  315. ### Improved: Renderer Performance
  316. - `ElementRenderer` is now `React.memo`'d for better performance with repeat lists
  317. - `emit` is always defined (never `undefined`)
  318. - Repeat scope passes the actual item object, eliminating string token rewriting
  319. ### Improved: Utilities
  320. - `applySpecPatch()` — typed wrapper for applying a single patch to a Spec
  321. - `nestedToFlat()` — convert nested tree specs to flat format
  322. - `resolveBindings()` / `resolveActionParam()` — resolve binding paths and action params
  323. ### Breaking Changes
  324. - `{ $path }` and `{ path }` replaced by `{ $state }`, `{ $item }`, `{ $index }` in props
  325. - Visibility: `{ path }` -> `{ $state }`, `{ and/or/not }` -> `{ $and/$or }` with `not` as operator flag
  326. - `DynamicValue`: `{ path: string }` -> `{ $state: string }`
  327. - `repeat.path` -> `repeat.statePath`
  328. - Action params: `path` -> `statePath` in setState action
  329. - `actionHandlers` -> `handlers` on `JSONUIProvider` / `ActionProvider`
  330. - `AuthState` and `{ auth }` visibility conditions removed (model auth as regular state)
  331. - Legacy catalog API removed: `createCatalog`, `generateCatalogPrompt`, `generateSystemPrompt`
  332. - React exports removed: `createRendererFromCatalog`, `rewriteRepeatTokens`
  333. - Codegen: `traverseTree` -> `traverseSpec`
  334. See the [Migration Guide](/docs/migration) for detailed upgrade instructions.
  335. ---
  336. ## v0.5.0
  337. February 2026
  338. ### New: @json-render/react-native
  339. Full React Native renderer with 25+ standard components, data binding, visibility, actions, and dynamic props. Build AI-generated native mobile UIs with the same catalog-driven approach as web.
  340. ```tsx
  341. import { defineCatalog } from "@json-render/core";
  342. import { schema } from "@json-render/react-native/schema";
  343. import {
  344. standardComponentDefinitions,
  345. standardActionDefinitions,
  346. } from "@json-render/react-native/catalog";
  347. import { defineRegistry, Renderer } from "@json-render/react-native";
  348. const catalog = defineCatalog(schema, {
  349. components: { ...standardComponentDefinitions },
  350. actions: standardActionDefinitions,
  351. });
  352. const { registry } = defineRegistry(catalog, { components: {} });
  353. <Renderer spec={spec} registry={registry} />
  354. ```
  355. Includes standard components for layout (Container, Row, Column, ScrollContainer, SafeArea, Pressable, Spacer, Divider), content (Heading, Paragraph, Label, Image, Avatar, Badge, Chip), input (Button, TextInput, Switch, Checkbox, Slider, SearchBar), feedback (Spinner, ProgressBar), and composite (Card, ListItem, Modal).
  356. ### New: Event System
  357. Components now use `emit` to fire named events instead of directly dispatching actions. The element's `on` field maps events to action bindings, decoupling component logic from action handling.
  358. ```tsx
  359. // Component emits a named event
  360. Button: ({ props, emit }) => (
  361. <button onClick={() => emit("press")}>{props.label}</button>
  362. ),
  363. // Element spec maps events to actions
  364. {
  365. "type": "Button",
  366. "props": { "label": "Submit" },
  367. "on": { "press": { "action": "submit", "params": { "formId": "main" } } }
  368. }
  369. ```
  370. ### New: Repeat/List Rendering
  371. Elements can now iterate over state arrays using the `repeat` field. Child elements use `{ "$item": "field" }` to read from the current item and `{ "$index": true }` for the current array index.
  372. ```json
  373. {
  374. "type": "Column",
  375. "repeat": { "statePath": "/posts", "key": "id" },
  376. "children": ["post-card"]
  377. }
  378. ```
  379. ```json
  380. {
  381. "type": "Card",
  382. "props": { "title": { "$item": "title" } }
  383. }
  384. ```
  385. ### New: User Prompt Builder
  386. Build structured user prompts with optional spec refinement and state context:
  387. ```typescript
  388. import { buildUserPrompt } from "@json-render/core";
  389. // Fresh generation
  390. buildUserPrompt({ prompt: "create a todo app" });
  391. // Refinement (patch-only mode)
  392. buildUserPrompt({ prompt: "add a toggle", currentSpec: spec });
  393. // With runtime state
  394. buildUserPrompt({ prompt: "show data", state: { todos: [] } });
  395. ```
  396. ### New: Spec Validation
  397. Validate spec structure and auto-fix common issues:
  398. ```typescript
  399. import { validateSpec, autoFixSpec } from "@json-render/core";
  400. const { valid, issues } = validateSpec(spec);
  401. const fixed = autoFixSpec(spec);
  402. ```
  403. ### Improved: State Management
  404. `DataProvider` has been renamed to `StateProvider` with a clearer API. State is now a first-class part of specs. Elements can bind to state via `$state` expressions, and the built-in `setState` action updates state directly.
  405. ### Improved: AI Prompts
  406. Schema prompts now include streaming best practices, repeat/list examples, and state patching guidance. Schemas can also define `defaultRules` that are always included in generated prompts.
  407. ### Improved: Documentation
  408. - All documentation pages migrated to MDX
  409. - AI-powered documentation chat
  410. - Dynamic Open Graph images for all docs pages
  411. - Improved playground
  412. ### Breaking Changes
  413. - `DataProvider` renamed to `StateProvider`
  414. - `useData` renamed to `useStateStore`, `useDataValue` to `useStateValue`, `useDataBinding` to `useStateBinding`
  415. - `onAction` renamed to `emit` in component context
  416. - `DataModel` type renamed to `StateModel`
  417. - `Action` type renamed to `ActionBinding` (old name still available but deprecated)
  418. ---
  419. ## v0.4.0
  420. February 2026
  421. ### New: Custom Schema System
  422. Create custom output formats with `defineSchema`. Each renderer now defines its own schema, enabling completely different spec formats for different use cases.
  423. ```typescript
  424. import { defineSchema } from "@json-render/core";
  425. const mySchema = defineSchema((s) => ({
  426. spec: s.object({
  427. pages: s.array(s.object({
  428. title: s.string(),
  429. blocks: s.array(s.ref("catalog.blocks")),
  430. })),
  431. }),
  432. catalog: s.object({
  433. blocks: s.map({ props: s.zod(), description: s.string() }),
  434. }),
  435. }), {
  436. promptTemplate: myPromptTemplate,
  437. });
  438. ```
  439. ### New: Component Slots
  440. Components can now define which slots they accept. Use `["default"]` for regular children, or named slots like `["header", "footer"]` for more complex layouts.
  441. ```typescript
  442. const catalog = defineCatalog(schema, {
  443. components: {
  444. Card: {
  445. props: z.object({ title: z.string() }),
  446. slots: ["default"], // accepts children
  447. description: "A card container",
  448. },
  449. Layout: {
  450. props: z.object({}),
  451. slots: ["header", "content", "footer"], // named slots
  452. description: "Page layout with header, content, footer",
  453. },
  454. },
  455. });
  456. ```
  457. ### New: AI Prompt Generation
  458. Catalogs now generate AI system prompts automatically with `catalog.prompt()`. The prompt includes all component definitions, props schemas, and action descriptions - ensuring the AI only generates valid specs.
  459. ```typescript
  460. import { defineCatalog } from "@json-render/core";
  461. import { schema } from "@json-render/react/schema";
  462. const catalog = defineCatalog(schema, {
  463. components: { /* ... */ },
  464. actions: { /* ... */ },
  465. });
  466. // Generate system prompt for AI
  467. const systemPrompt = catalog.prompt();
  468. // Use with any AI SDK
  469. const result = await streamText({
  470. model: "claude-haiku-4.5",
  471. system: systemPrompt,
  472. prompt: userMessage,
  473. });
  474. ```
  475. ### New: @json-render/remotion
  476. Generate AI-powered videos with Remotion. Define video catalogs, stream timeline specs, and render with the Remotion Player.
  477. ```tsx
  478. import { Player } from "@remotion/player";
  479. import { Renderer, schema, standardComponentDefinitions } from "@json-render/remotion";
  480. const catalog = defineCatalog(schema, {
  481. components: standardComponentDefinitions,
  482. transitions: standardTransitionDefinitions,
  483. });
  484. <Player
  485. component={Renderer}
  486. inputProps={{ spec }}
  487. durationInFrames={spec.composition.durationInFrames}
  488. fps={spec.composition.fps}
  489. compositionWidth={spec.composition.width}
  490. compositionHeight={spec.composition.height}
  491. />
  492. ```
  493. Includes 10 standard video components (TitleCard, TypingText, SplitScreen, etc.), 7 transition types, and the ClipWrapper utility for custom components.
  494. ### New: SpecStream
  495. SpecStream is json-render's streaming format for progressively building specs from JSONL patches. The new compiler API makes it easy to process streaming AI responses.
  496. ```typescript
  497. import { createSpecStreamCompiler } from "@json-render/core";
  498. const compiler = createSpecStreamCompiler<MySpec>();
  499. // Process streaming chunks
  500. const { result, newPatches } = compiler.push(chunk);
  501. setSpec(result); // Update UI with partial result
  502. ```
  503. ### Improved: Dashboard Example
  504. The dashboard example is now a full-featured accounting dashboard with:
  505. - Persistent SQLite database with Drizzle ORM
  506. - RESTful API for customers, invoices, expenses, accounts
  507. - Draggable widget reordering
  508. - AI-powered widget generation with streaming
  509. - Real data binding to database records
  510. ### Improved: Documentation
  511. - Interactive playground for testing specs
  512. - New guides: Custom Schema, Streaming, Code Export
  513. - Full API reference for all packages
  514. - Integration guides: A2UI, AG-UI, Adaptive Cards, OpenAPI
  515. ### Breaking Changes
  516. - `UITree` type renamed to `Spec`
  517. - Schema is now imported from renderer packages (`@json-render/react`) not core
  518. - `defineCatalog` now requires a schema as first argument
  519. ---
  520. ## v0.3.0
  521. January 2026
  522. Internal release with codegen foundations.
  523. - Added `@json-render/codegen` package (spec traversal and JSX serialization)
  524. - Configurable AI model via environment variables
  525. - Documentation improvements and bug fixes
  526. *Note: Only @json-render/core was published to npm for this release.*
  527. ---
  528. ## v0.2.0
  529. January 2026
  530. Initial public release.
  531. - Core catalog and spec types
  532. - React renderer with contexts for data, actions, visibility
  533. - AI prompt generation from catalogs
  534. - Basic streaming support
  535. - Dashboard example application