page.mdx 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992
  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.18.0
  6. April 17, 2026
  7. ### New: Devtools
  8. Five new packages for inspecting json-render apps in the browser:
  9. - `@json-render/devtools` -- framework-agnostic core
  10. - `@json-render/devtools-react`
  11. - `@json-render/devtools-vue`
  12. - `@json-render/devtools-svelte`
  13. - `@json-render/devtools-solid`
  14. Drop `<JsonRenderDevtools />` into your app to get a shadow-DOM-isolated panel with six tabs (Spec, State, Actions, Stream, Catalog, Pick), a DOM picker that maps clicked elements back to spec keys via `data-jr-key`, and a capped event store. Toggle with the floating button or `Cmd`/`Ctrl` + `Shift` + `J`. Tree-shakes to `null` in production.
  15. ```bash
  16. npm install @json-render/devtools-react
  17. ```
  18. ```tsx
  19. import { JsonRenderDevtools } from "@json-render/devtools-react";
  20. <JsonRenderDevtools />
  21. ```
  22. See the [Devtools guide](/docs/devtools) and the [API reference](/docs/api/devtools) for details.
  23. ### New: Devtools Example
  24. New `examples/devtools` Next.js demo showing the full devtools panel wired up to an AI chat endpoint and a component catalog.
  25. ### New: Action Observer and Devtools Flag in Core
  26. `@json-render/core` now exposes an action observer and a devtools enablement flag that framework adapters use to mirror actions and stream events into the panel.
  27. ### Fixed: Zod 4 Schema Formatting
  28. `formatZodType` now correctly handles `z.record()`, `z.default()`, and `z.literal()` types from Zod 4, which previously produced incorrect or empty output in generated prompts and schemas.
  29. ---
  30. ## v0.17.0
  31. April 10, 2026
  32. ### New: Gaussian Splatting
  33. Added `GaussianSplat` component to `@json-render/react-three-fiber`, bringing the component count to 20. Composable with all existing R3F components (lights, controls, post-processing) via drei's Splat loader.
  34. ### New: R3F Gaussian Splatting Example
  35. Demo app with five scenes: splat showroom, splat with primitives, multi-splat, post-processing effects, and animated floating splat.
  36. ### New: Standalone gsplat Example
  37. Experimental demo app showcasing Gaussian Splatting with gsplat.js (no Three.js dependency), featuring scene selector, live JSON spec viewer, and progress indicator.
  38. ### Improved: AI Output Quality
  39. Improved prompt output and schema generation for more reliable AI-generated specs.
  40. ---
  41. ## v0.16.0
  42. March 27, 2026
  43. ### New: `@json-render/next`
  44. Next.js renderer that turns JSON specs into full Next.js applications with routes, layouts, SSR, metadata, data loaders, and static generation. Client and server entry points at `@json-render/next` and `@json-render/next/server`. Includes built-in `Link`, `Slot`, error boundary, loading, and not-found components.
  45. ```bash
  46. npm install @json-render/next
  47. ```
  48. ### New: `@json-render/shadcn-svelte`
  49. Pre-built shadcn-svelte components for json-render Svelte apps. 36 components built on Svelte 5 + Tailwind CSS with state binding, validation, and action support. Server-safe catalog at `@json-render/shadcn-svelte/catalog`.
  50. ```bash
  51. npm install @json-render/shadcn-svelte
  52. ```
  53. ### Improved: Release Process
  54. Switched from Changesets to a manual single-PR release workflow with changelog markers and automatic npm publish on version bump.
  55. ---
  56. ## v0.15.0
  57. March 23, 2026
  58. ### New: `@json-render/ink`
  59. Terminal renderer for json-render. JSON becomes terminal UIs powered by [Ink](https://github.com/vadimdemedes/ink). Stream AI-generated specs directly to the terminal with `useUIStream`.
  60. ```bash
  61. npm install @json-render/ink
  62. ```
  63. ### Improved: YAML Format Support in `buildUserPrompt`
  64. `buildUserPrompt` now accepts `format` and `serializer` options, enabling YAML as a wire format alongside JSON.
  65. ---
  66. ## v0.14.0
  67. March 13, 2026
  68. ### New: `@json-render/yaml`
  69. YAML wire format for json-render. Includes streaming YAML parser, `yamlPrompt()` for system prompts, and AI SDK transform (`pipeYamlRender`) as a drop-in alternative to JSONL streaming. Supports four fence types: `yaml-spec`, `yaml-edit`, `yaml-patch`, and `diff`.
  70. ```bash
  71. npm install @json-render/yaml
  72. ```
  73. ### New: Universal Edit Modes
  74. Three strategies for multi-turn spec refinement in `@json-render/core`:
  75. - **Patch** -- RFC 6902 JSON Patch
  76. - **Merge** -- RFC 7396 Merge Patch
  77. - **Diff** -- Unified diff
  78. New `editModes` option on `buildUserPrompt()` and `PromptOptions`. New helpers: `deepMergeSpec()`, `diffToPatches()`, `buildEditUserPrompt()`, `buildEditInstructions()`, `isNonEmptySpec()`.
  79. ### Improved: Playground
  80. Format toggle (JSONL / YAML), edit mode picker (patch / merge / diff), and token usage display with prompt caching stats.
  81. ### Improved: Prompt Caching
  82. Generate API uses Anthropic ephemeral cache control for system prompts.
  83. ---
  84. ## v0.13.0
  85. March 12, 2026
  86. ### New: `@json-render/solid`
  87. SolidJS renderer for json-render. JSON becomes Solid components with reactive rendering, schema export, and full catalog support.
  88. ```bash
  89. npm install @json-render/core @json-render/solid
  90. ```
  91. ### New: `@json-render/react-three-fiber`
  92. React Three Fiber renderer for json-render. JSON becomes 3D scenes with 19 built-in components for meshes, lights, models, environments, text, cameras, and controls.
  93. ```bash
  94. npm install @json-render/react-three-fiber
  95. ```
  96. ### Improved: Strict JSON Schema Mode
  97. `catalog.jsonSchema({ strict: true })` produces a JSON Schema subset compatible with LLM structured output APIs (OpenAI, Google Gemini, Anthropic). Ensures `additionalProperties: false` on every object and all properties listed in `required`.
  98. ---
  99. ## v0.12.1
  100. March 11, 2026
  101. ### Changed: Generation Mode Renames
  102. Renamed generation modes from `"generate"` / `"chat"` to `"standalone"` / `"inline"`. The old names still work but emit a deprecation warning.
  103. ### Fixed: MCP React Duplicate Module Error
  104. Resolved React duplicate module error (`useRef` returning null) in `@json-render/mcp` by adding `resolve.dedupe` Vite configuration. Added `./build-app-html` export entry point.
  105. ---
  106. ## v0.12.0
  107. March 6, 2026
  108. ### New: `@json-render/svelte`
  109. Svelte 5 renderer with runes-based reactivity. Full support for data binding, visibility, actions, validation, watchers, streaming, and repeat scopes. Includes `defineRegistry`, `Renderer`, `schema`, composables, and context providers.
  110. ```bash
  111. npm install @json-render/core @json-render/svelte
  112. ```
  113. ### New: `@json-render/react-email`
  114. React Email renderer for generating HTML and plain-text emails from JSON specs. 17 standard components (Html, Head, Body, Container, Section, Row, Column, Heading, Text, Link, Button, Image, Hr, Preview, Markdown). Server-side `renderToHtml` / `renderToPlainText` APIs.
  115. ```bash
  116. npm install @json-render/react-email
  117. ```
  118. ### New: `@json-render/mcp`
  119. MCP Apps integration that serves json-render UIs as interactive apps inside Claude, ChatGPT, Cursor, VS Code, and other MCP-capable clients. `createMcpApp` server factory, `useJsonRenderApp` React hook for iframes, and `buildAppHtml` utility.
  120. ```bash
  121. npm install @json-render/mcp
  122. ```
  123. ---
  124. ## v0.11.0
  125. February 27, 2026
  126. ### New: `@json-render/image`
  127. Server-side image renderer powered by Satori. Turns the same `{ root, elements }` spec format into SVG or PNG output for OG images, social cards, and banners.
  128. ```bash
  129. npm install @json-render/image
  130. ```
  131. ```typescript
  132. import { renderToSvg, renderToPng } from "@json-render/image/render";
  133. import { standardComponentDefinitions } from "@json-render/image/catalog";
  134. const svg = await renderToSvg(spec, { width: 1200, height: 630 });
  135. const png = await renderToPng(spec, { width: 1200, height: 630 });
  136. ```
  137. 9 standard components: Frame, Box, Row, Column, Heading, Text, Image, Divider, Spacer. Server-safe import path at `@json-render/image/server`.
  138. ---
  139. ## v0.10.0
  140. February 25, 2026
  141. ### New: `@json-render/vue`
  142. 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.
  143. ```bash
  144. npm install @json-render/core @json-render/vue
  145. ```
  146. ```typescript
  147. import { h } from "vue";
  148. import { defineRegistry, Renderer } from "@json-render/vue";
  149. import { schema } from "@json-render/vue/schema";
  150. const { registry } = defineRegistry(catalog, {
  151. components: {
  152. Card: ({ props, children }) =>
  153. h("div", { class: "card" }, [h("h3", null, props.title), children]),
  154. Button: ({ props, emit }) =>
  155. h("button", { onClick: () => emit("press") }, props.label),
  156. },
  157. });
  158. ```
  159. Providers: `StateProvider`, `ActionProvider`, `VisibilityProvider`, `ValidationProvider`. Composables: `useStateStore`, `useStateValue`, `useActions`, `useAction`, `useIsVisible`, `useFieldValidation`, `useBoundProp`, `useUIStream`, `useChatUI`.
  160. See the [Vue API reference](/docs/api/vue) for details.
  161. ### New: `@json-render/xstate`
  162. [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.
  163. ```bash
  164. npm install @json-render/xstate @xstate/store
  165. ```
  166. ```typescript
  167. import { createAtom } from "@xstate/store";
  168. import { xstateStoreStateStore } from "@json-render/xstate";
  169. const atom = createAtom({ count: 0 });
  170. const store = xstateStoreStateStore({ atom });
  171. ```
  172. Requires `@xstate/store` v3+.
  173. ### New: `$computed` and `$template` Expressions
  174. Two new prop expression types for dynamic values:
  175. - **`$template`** -- interpolate state values into strings: `{ "$template": "Hello, ${/user/name}!" }`
  176. - **`$computed`** -- call registered functions: `{ "$computed": "fullName", "args": { "first": { "$state": "/form/firstName" } } }`
  177. Register functions via the `functions` prop on `JSONUIProvider` or `createRenderer`. See [Computed Values](/docs/computed-values) for details.
  178. ### New: State Watchers
  179. Elements can declare a `watch` field to trigger actions when state values change. Useful for cascading dependencies like country/city selects.
  180. ```json
  181. {
  182. "type": "Select",
  183. "props": { "value": { "$bindState": "/form/country" }, "options": ["US", "Canada"] },
  184. "watch": {
  185. "/form/country": { "action": "loadCities", "params": { "country": { "$state": "/form/country" } } }
  186. }
  187. }
  188. ```
  189. `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.
  190. ### New: Cross-Field Validation
  191. New built-in validation functions for cross-field comparisons:
  192. - `equalTo` -- alias for `matches` with clearer semantics
  193. - `lessThan` -- value must be less than another field
  194. - `greaterThan` -- value must be greater than another field
  195. - `requiredIf` -- required only when a condition field is truthy
  196. Validation check args now resolve through `resolvePropValue`, so `$state` expressions work consistently.
  197. ### New: `validateForm` Action
  198. Built-in action (React) that validates all registered form fields at once and writes `{ valid, errors }` to state:
  199. ```json
  200. {
  201. "on": {
  202. "press": [
  203. { "action": "validateForm", "params": { "statePath": "/formResult" } },
  204. { "action": "submitForm" }
  205. ]
  206. }
  207. }
  208. ```
  209. ### Improved: shadcn/ui Validation
  210. All form components now support `checks` and `validateOn` props:
  211. - Checkbox, Radio, Switch added validation support
  212. - `validateOn` controls timing: `"change"` (default for Select, Checkbox, Radio, Switch), `"blur"` (default for Input, Textarea), or `"submit"`
  213. ### New Examples
  214. - **Vue example** -- standalone Vue 3 app with custom components
  215. - **Vite Renderers** -- side-by-side React and Vue renderers with shared catalog
  216. ---
  217. ## v0.9.1
  218. February 24, 2026
  219. ### Fixed: Install failure due to private dependency
  220. `@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.
  221. ---
  222. ## v0.9.0
  223. February 24, 2026
  224. ### New: External State Store
  225. 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.
  226. - Added `StateStore` interface and `createStateStore()` factory to `@json-render/core`
  227. - `StateProvider`, `JSONUIProvider`, and `createRenderer` now accept an optional `store` prop
  228. - When `store` is provided, it becomes the single source of truth (`initialState`/`onStateChange` are ignored)
  229. - When `store` is omitted, everything works exactly as before (fully backward compatible)
  230. - Applied across all platform packages: react, react-native, react-pdf
  231. - Store utilities (`createStoreAdapter`, `immutableSetByPath`, `flattenToPointers`) available via `@json-render/core/store-utils` for building custom adapters
  232. New adapter packages: `@json-render/redux`, `@json-render/zustand`, `@json-render/jotai`.
  233. See the [Data Binding](/docs/data-binding#external-store-controlled-mode) guide for usage.
  234. ### Changed: `onStateChange` signature updated (breaking)
  235. 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:
  236. ```ts
  237. // Before
  238. onStateChange?: (path: string, value: unknown) => void
  239. // After
  240. onStateChange?: (changes: Array<{ path: string; value: unknown }>) => void
  241. ```
  242. 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.
  243. ### Fixed: Server-safe schema import
  244. `@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`.
  245. For combined imports, split into separate `schema` (subpath) and client API (main entry) lines:
  246. ```ts
  247. import { schema } from "@json-render/react/schema";
  248. import { defineRegistry, Renderer } from "@json-render/react";
  249. ```
  250. ### Fixed: Chaining actions
  251. 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`.
  252. ### Fixed: Zod array inner type resolution
  253. Fixed safely resolving the inner type for Zod arrays in schema introspection, preventing errors when catalog component props use `z.array()`.
  254. ---
  255. ## v0.8.0
  256. February 20, 2026
  257. ### New: `@json-render/react-pdf`
  258. 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.
  259. ```bash
  260. npm install @json-render/core @json-render/react-pdf
  261. ```
  262. ```typescript
  263. import { renderToBuffer } from "@json-render/react-pdf";
  264. import type { Spec } from "@json-render/core";
  265. const spec: Spec = {
  266. root: "doc",
  267. elements: {
  268. doc: { type: "Document", props: { title: "Invoice" }, children: ["page"] },
  269. page: {
  270. type: "Page",
  271. props: { size: "A4" },
  272. children: ["heading", "table"],
  273. },
  274. heading: {
  275. type: "Heading",
  276. props: { text: "Invoice #1234", level: "h1" },
  277. children: [],
  278. },
  279. table: {
  280. type: "Table",
  281. props: {
  282. columns: [
  283. { header: "Item", width: "60%" },
  284. { header: "Price", width: "40%", align: "right" },
  285. ],
  286. rows: [
  287. ["Widget A", "$10.00"],
  288. ["Widget B", "$25.00"],
  289. ],
  290. },
  291. children: [],
  292. },
  293. },
  294. };
  295. const buffer = await renderToBuffer(spec);
  296. ```
  297. Server-side rendering APIs:
  298. - `renderToBuffer(spec)` -- render to an in-memory PDF buffer
  299. - `renderToStream(spec)` -- render to a readable stream (pipe to HTTP response)
  300. - `renderToFile(spec, path)` -- render directly to a file
  301. 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).
  302. Supports custom catalogs with `defineRegistry`, server-safe imports via `@json-render/react-pdf/server`, and full context support (state, visibility, actions, validation, repeat scopes).
  303. ---
  304. ## v0.7.0
  305. February 17, 2026
  306. ### New: `@json-render/shadcn`
  307. 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`.
  308. ```bash
  309. npm install @json-render/shadcn
  310. ```
  311. ```typescript
  312. import { defineCatalog } from "@json-render/core";
  313. import { schema } from "@json-render/react/schema";
  314. import { shadcnComponentDefinitions } from "@json-render/shadcn/catalog";
  315. import { defineRegistry } from "@json-render/react";
  316. import { shadcnComponents } from "@json-render/shadcn";
  317. const catalog = defineCatalog(schema, {
  318. components: {
  319. Card: shadcnComponentDefinitions.Card,
  320. Button: shadcnComponentDefinitions.Button,
  321. Input: shadcnComponentDefinitions.Input,
  322. },
  323. actions: {},
  324. });
  325. const { registry } = defineRegistry(catalog, {
  326. components: {
  327. Card: shadcnComponents.Card,
  328. Button: shadcnComponents.Button,
  329. Input: shadcnComponents.Input,
  330. },
  331. });
  332. ```
  333. 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).
  334. See the [API reference](/docs/api/shadcn) for full details.
  335. ### New: Event Handles (`on()`)
  336. Components now receive an `on(event)` function in addition to `emit(event)`. The `on()` function returns an `EventHandle` with metadata:
  337. - `emit()` -- fire the event
  338. - `shouldPreventDefault` -- whether any action binding requested `preventDefault`
  339. - `bound` -- whether any handler is bound to this event
  340. ```tsx
  341. Link: ({ props, on }) => {
  342. const click = on("click");
  343. return (
  344. <a href={props.href} onClick={(e) => {
  345. if (click.shouldPreventDefault) e.preventDefault();
  346. click.emit();
  347. }}>{props.label}</a>
  348. );
  349. },
  350. ```
  351. ### New: `BaseComponentProps`
  352. 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.
  353. ```typescript
  354. import type { BaseComponentProps } from "@json-render/react";
  355. const Card = ({ props, children }: BaseComponentProps<{ title?: string }>) => (
  356. <div>{props.title}{children}</div>
  357. );
  358. ```
  359. ### New: Built-in Actions in Schema
  360. 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`.
  361. ### New: `preventDefault` on `ActionBinding`
  362. Action bindings now support a `preventDefault` boolean field, allowing the LLM to request that default browser behavior (e.g. navigation on links) be prevented.
  363. ### Improved: Stream Transform Text Block Splitting
  364. `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`.
  365. ### Improved: `defineRegistry` Actions Requirement
  366. `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.
  367. ---
  368. ## v0.6.0
  369. February 13, 2026
  370. ### New: Chat Mode (Inline GenUI)
  371. > **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.
  372. 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.
  373. ```typescript
  374. // Generate mode (default) — AI outputs only JSONL
  375. const prompt = catalog.prompt();
  376. // Chat mode — AI outputs text + JSONL inline
  377. const chatPrompt = catalog.prompt({ mode: "chat" });
  378. ```
  379. On the server, `pipeJsonRender()` separates text from JSONL patches in a mixed stream:
  380. ```typescript
  381. import { pipeJsonRender } from "@json-render/core";
  382. import { createUIMessageStream, createUIMessageStreamResponse } from "ai";
  383. const stream = createUIMessageStream({
  384. execute: async ({ writer }) => {
  385. writer.merge(pipeJsonRender(result.toUIMessageStream()));
  386. },
  387. });
  388. return createUIMessageStreamResponse({ stream });
  389. ```
  390. On the client, `useJsonRenderMessage` extracts the spec and text from message parts:
  391. ```tsx
  392. import { useJsonRenderMessage } from "@json-render/react";
  393. function ChatMessage({ message }) {
  394. const { spec, text, hasSpec } = useJsonRenderMessage(message.parts);
  395. return (
  396. <div>
  397. {text && <Markdown>{text}</Markdown>}
  398. {hasSpec && <Renderer spec={spec} registry={registry} />}
  399. </div>
  400. );
  401. }
  402. ```
  403. ### New: AI SDK Integration
  404. First-class Vercel AI SDK support with typed data parts and stream utilities.
  405. - `SpecDataPart` type for `data-spec` stream parts (patch, flat, nested payloads)
  406. - `SPEC_DATA_PART` / `SPEC_DATA_PART_TYPE` constants for type-safe part filtering
  407. - `createJsonRenderTransform()` low-level TransformStream for custom pipelines
  408. - `createMixedStreamParser()` for parsing mixed text + JSONL streams
  409. ### New: Two-Way Binding
  410. 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.
  411. ```json
  412. {
  413. "type": "Input",
  414. "props": { "label": "Email", "value": { "$bindState": "/form/email" } }
  415. }
  416. ```
  417. ```tsx
  418. import { useBoundProp } from "@json-render/react";
  419. Input: ({ props, bindings }) => {
  420. const [value, setValue] = useBoundProp<string>(props.value, bindings?.value);
  421. return <input value={value ?? ""} onChange={(e) => setValue(e.target.value)} />;
  422. }
  423. ```
  424. ### New: Expression-Based Props and Visibility
  425. 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.
  426. **Props:**
  427. ```json
  428. { "title": { "$state": "/user/name" } }
  429. { "label": { "$item": "title" } }
  430. { "position": { "$index": true } }
  431. ```
  432. **Visibility:**
  433. ```json
  434. { "$state": "/isAdmin" }
  435. { "$state": "/role", "eq": "admin" }
  436. [{ "$state": "/isAdmin" }, { "$state": "/feature" }]
  437. { "$or": [{ "$state": "/roleA" }, { "$state": "/roleB" }] }
  438. { "$item": "isActive" }
  439. { "$index": true, "gt": 0 }
  440. ```
  441. Comparison operators: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `not`.
  442. ### New: React Chat Hooks
  443. - `useChatUI()` — full chat hook with message history, streaming, and spec extraction
  444. - `useJsonRenderMessage()` — extract spec + text from a message's parts array
  445. - `buildSpecFromParts()` / `getTextFromParts()` — utilities for working with AI SDK message parts
  446. - `useBoundProp()` — two-way binding hook for `$bindState` / `$bindItem`
  447. ### New: Chat Example
  448. Full-featured chat example (`examples/chat`) with AI agent, tool calls (crypto, GitHub, Hacker News, weather, search), theme toggle, and streaming inline UI generation.
  449. ### Improved: Renderer Performance
  450. - `ElementRenderer` is now `React.memo`'d for better performance with repeat lists
  451. - `emit` is always defined (never `undefined`)
  452. - Repeat scope passes the actual item object, eliminating string token rewriting
  453. ### Improved: Utilities
  454. - `applySpecPatch()` — typed wrapper for applying a single patch to a Spec
  455. - `nestedToFlat()` — convert nested tree specs to flat format
  456. - `resolveBindings()` / `resolveActionParam()` — resolve binding paths and action params
  457. ### Breaking Changes
  458. - `{ $path }` and `{ path }` replaced by `{ $state }`, `{ $item }`, `{ $index }` in props
  459. - Visibility: `{ path }` -> `{ $state }`, `{ and/or/not }` -> `{ $and/$or }` with `not` as operator flag
  460. - `DynamicValue`: `{ path: string }` -> `{ $state: string }`
  461. - `repeat.path` -> `repeat.statePath`
  462. - Action params: `path` -> `statePath` in setState action
  463. - `actionHandlers` -> `handlers` on `JSONUIProvider` / `ActionProvider`
  464. - `AuthState` and `{ auth }` visibility conditions removed (model auth as regular state)
  465. - Legacy catalog API removed: `createCatalog`, `generateCatalogPrompt`, `generateSystemPrompt`
  466. - React exports removed: `createRendererFromCatalog`, `rewriteRepeatTokens`
  467. - Codegen: `traverseTree` -> `traverseSpec`
  468. See the [Migration Guide](/docs/migration) for detailed upgrade instructions.
  469. ---
  470. ## v0.5.0
  471. February 9, 2026
  472. ### New: @json-render/react-native
  473. 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.
  474. ```tsx
  475. import { defineCatalog } from "@json-render/core";
  476. import { schema } from "@json-render/react-native/schema";
  477. import {
  478. standardComponentDefinitions,
  479. standardActionDefinitions,
  480. } from "@json-render/react-native/catalog";
  481. import { defineRegistry, Renderer } from "@json-render/react-native";
  482. const catalog = defineCatalog(schema, {
  483. components: { ...standardComponentDefinitions },
  484. actions: standardActionDefinitions,
  485. });
  486. const { registry } = defineRegistry(catalog, { components: {} });
  487. <Renderer spec={spec} registry={registry} />
  488. ```
  489. 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).
  490. ### New: Event System
  491. 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.
  492. ```tsx
  493. // Component emits a named event
  494. Button: ({ props, emit }) => (
  495. <button onClick={() => emit("press")}>{props.label}</button>
  496. ),
  497. // Element spec maps events to actions
  498. {
  499. "type": "Button",
  500. "props": { "label": "Submit" },
  501. "on": { "press": { "action": "submit", "params": { "formId": "main" } } }
  502. }
  503. ```
  504. ### New: Repeat/List Rendering
  505. 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.
  506. ```json
  507. {
  508. "type": "Column",
  509. "repeat": { "statePath": "/posts", "key": "id" },
  510. "children": ["post-card"]
  511. }
  512. ```
  513. ```json
  514. {
  515. "type": "Card",
  516. "props": { "title": { "$item": "title" } }
  517. }
  518. ```
  519. ### New: User Prompt Builder
  520. Build structured user prompts with optional spec refinement and state context:
  521. ```typescript
  522. import { buildUserPrompt } from "@json-render/core";
  523. // Fresh generation
  524. buildUserPrompt({ prompt: "create a todo app" });
  525. // Refinement (patch-only mode)
  526. buildUserPrompt({ prompt: "add a toggle", currentSpec: spec });
  527. // With runtime state
  528. buildUserPrompt({ prompt: "show data", state: { todos: [] } });
  529. ```
  530. ### New: Spec Validation
  531. Validate spec structure and auto-fix common issues:
  532. ```typescript
  533. import { validateSpec, autoFixSpec } from "@json-render/core";
  534. const { valid, issues } = validateSpec(spec);
  535. const fixed = autoFixSpec(spec);
  536. ```
  537. ### Improved: State Management
  538. `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.
  539. ### Improved: AI Prompts
  540. 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.
  541. ### Improved: Documentation
  542. - All documentation pages migrated to MDX
  543. - AI-powered documentation chat
  544. - Dynamic Open Graph images for all docs pages
  545. - Improved playground
  546. ### Breaking Changes
  547. - `DataProvider` renamed to `StateProvider`
  548. - `useData` renamed to `useStateStore`, `useDataValue` to `useStateValue`, `useDataBinding` to `useStateBinding`
  549. - `onAction` renamed to `emit` in component context
  550. - `DataModel` type renamed to `StateModel`
  551. - `Action` type renamed to `ActionBinding` (old name still available but deprecated)
  552. ---
  553. ## v0.4.0
  554. February 5, 2026
  555. ### New: Custom Schema System
  556. Create custom output formats with `defineSchema`. Each renderer now defines its own schema, enabling completely different spec formats for different use cases.
  557. ```typescript
  558. import { defineSchema } from "@json-render/core";
  559. const mySchema = defineSchema((s) => ({
  560. spec: s.object({
  561. pages: s.array(s.object({
  562. title: s.string(),
  563. blocks: s.array(s.ref("catalog.blocks")),
  564. })),
  565. }),
  566. catalog: s.object({
  567. blocks: s.map({ props: s.zod(), description: s.string() }),
  568. }),
  569. }), {
  570. promptTemplate: myPromptTemplate,
  571. });
  572. ```
  573. ### New: Component Slots
  574. Components can now define which slots they accept. Use `["default"]` for regular children, or named slots like `["header", "footer"]` for more complex layouts.
  575. ```typescript
  576. const catalog = defineCatalog(schema, {
  577. components: {
  578. Card: {
  579. props: z.object({ title: z.string() }),
  580. slots: ["default"], // accepts children
  581. description: "A card container",
  582. },
  583. Layout: {
  584. props: z.object({}),
  585. slots: ["header", "content", "footer"], // named slots
  586. description: "Page layout with header, content, footer",
  587. },
  588. },
  589. });
  590. ```
  591. ### New: AI Prompt Generation
  592. 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.
  593. ```typescript
  594. import { defineCatalog } from "@json-render/core";
  595. import { schema } from "@json-render/react/schema";
  596. const catalog = defineCatalog(schema, {
  597. components: { /* ... */ },
  598. actions: { /* ... */ },
  599. });
  600. // Generate system prompt for AI
  601. const systemPrompt = catalog.prompt();
  602. // Use with any AI SDK
  603. const result = await streamText({
  604. model: "claude-haiku-4.5",
  605. system: systemPrompt,
  606. prompt: userMessage,
  607. });
  608. ```
  609. ### New: @json-render/remotion
  610. Generate AI-powered videos with Remotion. Define video catalogs, stream timeline specs, and render with the Remotion Player.
  611. ```tsx
  612. import { Player } from "@remotion/player";
  613. import { Renderer, schema, standardComponentDefinitions } from "@json-render/remotion";
  614. const catalog = defineCatalog(schema, {
  615. components: standardComponentDefinitions,
  616. transitions: standardTransitionDefinitions,
  617. });
  618. <Player
  619. component={Renderer}
  620. inputProps={{ spec }}
  621. durationInFrames={spec.composition.durationInFrames}
  622. fps={spec.composition.fps}
  623. compositionWidth={spec.composition.width}
  624. compositionHeight={spec.composition.height}
  625. />
  626. ```
  627. Includes 10 standard video components (TitleCard, TypingText, SplitScreen, etc.), 7 transition types, and the ClipWrapper utility for custom components.
  628. ### New: SpecStream
  629. 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.
  630. ```typescript
  631. import { createSpecStreamCompiler } from "@json-render/core";
  632. const compiler = createSpecStreamCompiler<MySpec>();
  633. // Process streaming chunks
  634. const { result, newPatches } = compiler.push(chunk);
  635. setSpec(result); // Update UI with partial result
  636. ```
  637. ### Improved: Dashboard Example
  638. The dashboard example is now a full-featured accounting dashboard with:
  639. - Persistent SQLite database with Drizzle ORM
  640. - RESTful API for customers, invoices, expenses, accounts
  641. - Draggable widget reordering
  642. - AI-powered widget generation with streaming
  643. - Real data binding to database records
  644. ### Improved: Documentation
  645. - Interactive playground for testing specs
  646. - New guides: Custom Schema, Streaming, Code Export
  647. - Full API reference for all packages
  648. - Integration guides: A2UI, AG-UI, Adaptive Cards, OpenAPI
  649. ### Breaking Changes
  650. - `UITree` type renamed to `Spec`
  651. - Schema is now imported from renderer packages (`@json-render/react`) not core
  652. - `defineCatalog` now requires a schema as first argument
  653. ---
  654. ## v0.3.0
  655. January 20, 2026
  656. Internal release with codegen foundations.
  657. - Added `@json-render/codegen` package (spec traversal and JSX serialization)
  658. - Configurable AI model via environment variables
  659. - Documentation improvements and bug fixes
  660. *Note: Only @json-render/core was published to npm for this release.*
  661. ---
  662. ## v0.2.0
  663. January 14, 2026
  664. Initial public release.
  665. - Core catalog and spec types
  666. - React renderer with contexts for data, actions, visibility
  667. - AI prompt generation from catalogs
  668. - Basic streaming support
  669. - Dashboard example application