mirror of
https://github.com/vercel-labs/json-render.git
synced 2026-10-03 04:18:15 +08:00
Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
caa90b8b84 | ||
|
|
54a1ecf817 | ||
|
|
dc9e9d17f3 | ||
|
|
1977fb3a11 | ||
|
|
4606c01085 | ||
|
|
c1a700d719 | ||
|
|
6f15faaae0 | ||
|
|
63c339b4bb |
@@ -18,7 +18,8 @@
|
||||
"@json-render/vue",
|
||||
"@json-render/xstate",
|
||||
"@json-render/image",
|
||||
"@json-render/mcp"
|
||||
"@json-render/mcp",
|
||||
"@json-render/svelte"
|
||||
]
|
||||
],
|
||||
"linked": [],
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
node_modules
|
||||
.pnp
|
||||
.pnp.js
|
||||
.pnpm-store/
|
||||
|
||||
# Local env files
|
||||
.env*
|
||||
|
||||
@@ -98,7 +98,7 @@ When asked to prepare a release (e.g. "prepare v0.12.0"):
|
||||
- An API reference page at `apps/web/app/(main)/docs/api/<name>/page.mdx`
|
||||
- An entry in `apps/web/lib/page-titles.ts` and `apps/web/lib/docs-navigation.ts`
|
||||
- An entry in the docs-chat system prompt (`apps/web/app/api/docs-chat/route.ts`)
|
||||
- A skill at `skills/json-render-<name>/SKILL.md`
|
||||
- A skill at `skills/<name>/SKILL.md`
|
||||
- A `packages/<name>/README.md`
|
||||
6. **Run `pnpm type-check`** after all changes to verify nothing is broken
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ npm install @json-render/core @json-render/react-pdf
|
||||
npm install @json-render/core @json-render/react-email @react-email/components @react-email/render
|
||||
# or for Vue
|
||||
npm install @json-render/core @json-render/vue
|
||||
# or for Svelte
|
||||
npm install @json-render/core @json-render/svelte
|
||||
```
|
||||
|
||||
## Why json-render?
|
||||
@@ -28,7 +30,7 @@ json-render is a **Generative UI** framework: AI generates interfaces from natur
|
||||
- **Guardrailed** - AI can only use components in your catalog
|
||||
- **Predictable** - JSON output matches your schema, every time
|
||||
- **Fast** - Stream and render progressively as the model responds
|
||||
- **Cross-Platform** - React, Vue (web), React Native (mobile) from the same catalog
|
||||
- **Cross-Platform** - React, Vue, Svelte (web), React Native (mobile) from the same catalog
|
||||
- **Batteries Included** - 36 pre-built shadcn/ui components ready to use
|
||||
|
||||
## Quick Start
|
||||
@@ -116,12 +118,14 @@ function Dashboard({ spec }) {
|
||||
| `@json-render/core` | Schemas, catalogs, AI prompts, dynamic props, SpecStream utilities |
|
||||
| `@json-render/react` | React renderer, contexts, hooks |
|
||||
| `@json-render/vue` | Vue 3 renderer, composables, providers |
|
||||
| `@json-render/svelte` | Svelte 5 renderer with runes-based reactivity |
|
||||
| `@json-render/shadcn` | 36 pre-built shadcn/ui components (Radix UI + Tailwind CSS) |
|
||||
| `@json-render/react-native` | React Native renderer with standard mobile components |
|
||||
| `@json-render/remotion` | Remotion video renderer, timeline schema |
|
||||
| `@json-render/react-pdf` | React PDF renderer for generating PDF documents from specs |
|
||||
| `@json-render/react-email` | React Email renderer for HTML/plain-text emails from specs |
|
||||
| `@json-render/image` | Image renderer for SVG/PNG output (OG images, social cards) via Satori |
|
||||
| `@json-render/codegen` | Utilities for generating code from json-render UI trees |
|
||||
| `@json-render/redux` | Redux / Redux Toolkit adapter for `StateStore` |
|
||||
| `@json-render/zustand` | Zustand adapter for `StateStore` |
|
||||
| `@json-render/jotai` | Jotai adapter for `StateStore` |
|
||||
@@ -178,6 +182,23 @@ const { registry } = defineRegistry(catalog, {
|
||||
// <Renderer :spec="spec" :registry="registry" />
|
||||
```
|
||||
|
||||
### Svelte (UI)
|
||||
|
||||
```typescript
|
||||
import { defineRegistry, Renderer } from "@json-render/svelte";
|
||||
import { schema } from "@json-render/svelte/schema";
|
||||
|
||||
const { registry } = defineRegistry(catalog, {
|
||||
components: {
|
||||
Card: ({ props, children }) => /* Svelte 5 snippet */,
|
||||
Button: ({ props, emit }) => /* Svelte 5 snippet */,
|
||||
},
|
||||
});
|
||||
|
||||
// In your Svelte component:
|
||||
// <Renderer spec={spec} registry={registry} />
|
||||
```
|
||||
|
||||
### shadcn/ui (Web)
|
||||
|
||||
```tsx
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# web
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/codegen@0.12.1
|
||||
- @json-render/react@0.12.1
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/codegen@0.12.0
|
||||
- @json-render/react@0.12.0
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -3,7 +3,7 @@ export const metadata = pageMetadata("docs/ai-sdk")
|
||||
|
||||
# AI SDK Integration
|
||||
|
||||
Use json-render with the [Vercel AI SDK](https://sdk.vercel.ai) for seamless streaming. json-render supports two modes: **Generate** (standalone UI) and **Chat** (UI embedded in conversation). See [Generation Modes](/docs/generation-modes) for a detailed comparison.
|
||||
Use json-render with the [Vercel AI SDK](https://sdk.vercel.ai) for seamless streaming. json-render supports two modes: **Standalone** (standalone UI) and **Inline** (UI embedded in conversation). See [Generation Modes](/docs/generation-modes) for a detailed comparison.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -11,9 +11,9 @@ Use json-render with the [Vercel AI SDK](https://sdk.vercel.ai) for seamless str
|
||||
npm install ai @ai-sdk/react
|
||||
```
|
||||
|
||||
## Generate Mode
|
||||
## Standalone Mode
|
||||
|
||||
In generate mode, the AI outputs only JSONL patches. The entire response is a UI spec with no prose. This is the default mode and is ideal for playgrounds, builders, and dashboard generators.
|
||||
In standalone mode, the AI outputs only JSONL patches. The entire response is a UI spec with no prose. This is the default mode and is ideal for playgrounds, builders, and dashboard generators.
|
||||
|
||||
### API Route
|
||||
|
||||
@@ -73,9 +73,9 @@ function GenerativeUI() {
|
||||
}
|
||||
```
|
||||
|
||||
## Chat Mode
|
||||
## Inline Mode
|
||||
|
||||
In chat mode, the AI responds conversationally and includes JSONL patches inline. Text-only replies are allowed when no UI is needed. This is ideal for chatbots, copilots, and educational assistants.
|
||||
In inline mode, the AI responds conversationally and includes JSONL patches inline. Text-only replies are allowed when no UI is needed. This is ideal for chatbots, copilots, and educational assistants.
|
||||
|
||||
### API Route
|
||||
|
||||
@@ -96,7 +96,7 @@ export async function POST(req: Request) {
|
||||
|
||||
const result = streamText({
|
||||
model: yourModel,
|
||||
system: catalog.prompt({ mode: "chat" }),
|
||||
system: catalog.prompt({ mode: "inline" }),
|
||||
messages,
|
||||
});
|
||||
|
||||
@@ -182,13 +182,13 @@ const systemPrompt = catalog.prompt({
|
||||
});
|
||||
```
|
||||
|
||||
### Chat Mode Prompt
|
||||
### Inline Mode Prompt
|
||||
|
||||
```typescript
|
||||
const chatPrompt = catalog.prompt({ mode: "chat" });
|
||||
const inlinePrompt = catalog.prompt({ mode: "inline" });
|
||||
```
|
||||
|
||||
In chat mode, the prompt instructs the AI to respond conversationally first, then include JSONL patches on their own lines when UI is needed. Text-only replies are allowed.
|
||||
In inline mode, the prompt instructs the AI to respond conversationally first, then include JSONL patches on their own lines when UI is needed. Text-only replies are allowed.
|
||||
|
||||
## Which Mode?
|
||||
|
||||
@@ -197,8 +197,8 @@ In chat mode, the prompt instructs the AI to respond conversationally first, the
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Generate</th>
|
||||
<th>Chat</th>
|
||||
<th>Standalone</th>
|
||||
<th>Inline</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -215,7 +215,7 @@ In chat mode, the prompt instructs the AI to respond conversationally first, the
|
||||
<tr>
|
||||
<td>System prompt</td>
|
||||
<td><code>catalog.prompt()</code></td>
|
||||
<td><code>{"catalog.prompt({ mode: \"chat\" })"}</code></td>
|
||||
<td><code>{"catalog.prompt({ mode: \"inline\" })"}</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Stream utility</td>
|
||||
|
||||
@@ -75,7 +75,7 @@ interface Catalog {
|
||||
interface PromptOptions {
|
||||
system?: string; // Custom system message intro
|
||||
customRules?: string[]; // Additional rules to append
|
||||
mode?: "generate" | "chat"; // Output mode (default: "generate")
|
||||
mode?: "standalone" | "inline" | "generate" | "chat"; // Output mode (default: "standalone")
|
||||
}
|
||||
|
||||
interface SpecValidationResult<T> {
|
||||
@@ -370,7 +370,7 @@ Most users should use `pipeJsonRender()` instead, which wraps this transform for
|
||||
|
||||
### createMixedStreamParser
|
||||
|
||||
Parse a mixed stream of text and JSONL patches (used for Chat + GenUI mode):
|
||||
Parse a mixed stream of text and JSONL patches (used for Inline mode):
|
||||
|
||||
```typescript
|
||||
import { createMixedStreamParser } from '@json-render/core';
|
||||
@@ -389,7 +389,7 @@ parser.flush();
|
||||
|
||||
### pipeJsonRender
|
||||
|
||||
Pipe an AI SDK `UIMessageStream` through the json-render transform. Lines that parse as JSONL patches are emitted as `data-spec` parts; everything else passes through as text. Used in Chat mode API routes.
|
||||
Pipe an AI SDK `UIMessageStream` through the json-render transform. Lines that parse as JSONL patches are emitted as `data-spec` parts; everything else passes through as text. Used in Inline mode API routes.
|
||||
|
||||
```typescript
|
||||
import { pipeJsonRender } from '@json-render/core';
|
||||
@@ -403,7 +403,7 @@ const stream = createUIMessageStream({
|
||||
return createUIMessageStreamResponse({ stream });
|
||||
```
|
||||
|
||||
See [Generation Modes](/docs/generation-modes) for full Chat mode setup.
|
||||
See [Generation Modes](/docs/generation-modes) for full Inline mode setup.
|
||||
|
||||
### SpecStream Types
|
||||
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
import { pageMetadata } from "@/lib/page-metadata"
|
||||
export const metadata = pageMetadata("docs/api/jotai")
|
||||
|
||||
# @json-render/jotai
|
||||
|
||||
Jotai adapter for json-render's `StateStore` interface.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @json-render/jotai @json-render/core @json-render/react jotai
|
||||
```
|
||||
|
||||
## jotaiStateStore
|
||||
|
||||
Create a `StateStore` backed by a Jotai atom.
|
||||
|
||||
```typescript
|
||||
import { jotaiStateStore } from "@json-render/jotai";
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Type</th>
|
||||
<th>Required</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>atom</code></td>
|
||||
<td><code>{'WritableAtom<StateModel, [StateModel], void>'}</code></td>
|
||||
<td>Yes</td>
|
||||
<td>A writable atom holding the state model.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>store</code></td>
|
||||
<td>Jotai <code>Store</code></td>
|
||||
<td>No</td>
|
||||
<td>The Jotai store instance. Defaults to a new store created internally. Pass your own to share state with <code>{'<Provider>'}</code>.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Example
|
||||
|
||||
```typescript
|
||||
import { atom } from "jotai";
|
||||
import { jotaiStateStore } from "@json-render/jotai";
|
||||
import { StateProvider } from "@json-render/react";
|
||||
|
||||
const uiAtom = atom<Record<string, unknown>>({ count: 0 });
|
||||
const store = jotaiStateStore({ atom: uiAtom });
|
||||
```
|
||||
|
||||
```tsx
|
||||
<StateProvider store={store}>
|
||||
{/* json-render reads/writes go through Jotai */}
|
||||
</StateProvider>
|
||||
```
|
||||
|
||||
### Shared Jotai Store
|
||||
|
||||
If your app already uses a Jotai `<Provider>` with a custom store, pass it so both json-render and your components share the same state:
|
||||
|
||||
```typescript
|
||||
import { atom, createStore } from "jotai";
|
||||
import { Provider as JotaiProvider } from "jotai/react";
|
||||
import { jotaiStateStore } from "@json-render/jotai";
|
||||
import { StateProvider } from "@json-render/react";
|
||||
|
||||
const jStore = createStore();
|
||||
const uiAtom = atom<Record<string, unknown>>({ count: 0 });
|
||||
const store = jotaiStateStore({ atom: uiAtom, store: jStore });
|
||||
```
|
||||
|
||||
```tsx
|
||||
<JotaiProvider store={jStore}>
|
||||
<StateProvider store={store}>
|
||||
{/* Both json-render and useAtom() see the same state */}
|
||||
</StateProvider>
|
||||
</JotaiProvider>
|
||||
```
|
||||
|
||||
## Re-exports
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Export</th>
|
||||
<th>Source</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>StateStore</code></td>
|
||||
<td><code>@json-render/core</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -0,0 +1,104 @@
|
||||
import { pageMetadata } from "@/lib/page-metadata"
|
||||
export const metadata = pageMetadata("docs/api/redux")
|
||||
|
||||
# @json-render/redux
|
||||
|
||||
Redux / Redux Toolkit adapter for json-render's `StateStore` interface.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @json-render/redux @json-render/core @json-render/react redux
|
||||
# or with Redux Toolkit (recommended):
|
||||
npm install @json-render/redux @json-render/core @json-render/react @reduxjs/toolkit
|
||||
```
|
||||
|
||||
## reduxStateStore
|
||||
|
||||
Create a `StateStore` backed by a Redux store.
|
||||
|
||||
```typescript
|
||||
import { reduxStateStore } from "@json-render/redux";
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Type</th>
|
||||
<th>Required</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>store</code></td>
|
||||
<td><code>Store</code></td>
|
||||
<td>Yes</td>
|
||||
<td>The Redux store instance.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>selector</code></td>
|
||||
<td><code>{'(state: S) => StateModel'}</code></td>
|
||||
<td>No</td>
|
||||
<td>Select the json-render slice from the Redux state tree. Defaults to <code>{'(state) => state'}</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>dispatch</code></td>
|
||||
<td><code>{'(nextState: StateModel, store: Store) => void'}</code></td>
|
||||
<td>Yes</td>
|
||||
<td>Dispatch an action that replaces the selected slice with the next state.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Example
|
||||
|
||||
```typescript
|
||||
import { configureStore, createSlice } from "@reduxjs/toolkit";
|
||||
import { reduxStateStore } from "@json-render/redux";
|
||||
import { StateProvider } from "@json-render/react";
|
||||
|
||||
const uiSlice = createSlice({
|
||||
name: "ui",
|
||||
initialState: { count: 0 } as Record<string, unknown>,
|
||||
reducers: {
|
||||
replaceUiState: (_state, action) => action.payload,
|
||||
},
|
||||
});
|
||||
|
||||
const reduxStore = configureStore({
|
||||
reducer: { ui: uiSlice.reducer },
|
||||
});
|
||||
|
||||
const store = reduxStateStore({
|
||||
store: reduxStore,
|
||||
selector: (state) => state.ui,
|
||||
dispatch: (next, s) => s.dispatch(uiSlice.actions.replaceUiState(next)),
|
||||
});
|
||||
```
|
||||
|
||||
```tsx
|
||||
<StateProvider store={store}>
|
||||
{/* json-render reads/writes go through Redux */}
|
||||
</StateProvider>
|
||||
```
|
||||
|
||||
## Re-exports
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Export</th>
|
||||
<th>Source</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>StateStore</code></td>
|
||||
<td><code>@json-render/core</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -0,0 +1,77 @@
|
||||
import { pageMetadata } from "@/lib/page-metadata"
|
||||
export const metadata = pageMetadata("docs/api/xstate")
|
||||
|
||||
# @json-render/xstate
|
||||
|
||||
[XState Store](https://stately.ai/docs/xstate-store) adapter for json-render's `StateStore` interface.
|
||||
|
||||
Requires `@xstate/store` v3+.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @json-render/xstate @json-render/core @json-render/react @xstate/store
|
||||
```
|
||||
|
||||
## xstateStoreStateStore
|
||||
|
||||
Create a `StateStore` backed by an `@xstate/store` atom.
|
||||
|
||||
```typescript
|
||||
import { xstateStoreStateStore } from "@json-render/xstate";
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Type</th>
|
||||
<th>Required</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>atom</code></td>
|
||||
<td><code>{'Atom<StateModel>'}</code></td>
|
||||
<td>Yes</td>
|
||||
<td>An <code>@xstate/store</code> atom (from <code>createAtom</code>) holding the json-render state model.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Example
|
||||
|
||||
```typescript
|
||||
import { createAtom } from "@xstate/store";
|
||||
import { xstateStoreStateStore } from "@json-render/xstate";
|
||||
import { StateProvider } from "@json-render/react";
|
||||
|
||||
const uiAtom = createAtom({ count: 0 });
|
||||
const store = xstateStoreStateStore({ atom: uiAtom });
|
||||
```
|
||||
|
||||
```tsx
|
||||
<StateProvider store={store}>
|
||||
{/* json-render reads/writes go through @xstate/store */}
|
||||
</StateProvider>
|
||||
```
|
||||
|
||||
## Re-exports
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Export</th>
|
||||
<th>Source</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>StateStore</code></td>
|
||||
<td><code>@json-render/core</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -0,0 +1,108 @@
|
||||
import { pageMetadata } from "@/lib/page-metadata"
|
||||
export const metadata = pageMetadata("docs/api/zustand")
|
||||
|
||||
# @json-render/zustand
|
||||
|
||||
Zustand adapter for json-render's `StateStore` interface.
|
||||
|
||||
Requires Zustand v5+. Zustand v4 is not supported due to breaking API changes in the vanilla store interface.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @json-render/zustand @json-render/core @json-render/react zustand
|
||||
```
|
||||
|
||||
## zustandStateStore
|
||||
|
||||
Create a `StateStore` backed by a Zustand vanilla store.
|
||||
|
||||
```typescript
|
||||
import { zustandStateStore } from "@json-render/zustand";
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Option</th>
|
||||
<th>Type</th>
|
||||
<th>Required</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>store</code></td>
|
||||
<td><code>{'StoreApi<S>'}</code></td>
|
||||
<td>Yes</td>
|
||||
<td>A Zustand vanilla store (from <code>createStore</code> in <code>zustand/vanilla</code>).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>selector</code></td>
|
||||
<td><code>{'(state: S) => StateModel'}</code></td>
|
||||
<td>No</td>
|
||||
<td>Select the json-render slice from the store state. Defaults to the entire state.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>updater</code></td>
|
||||
<td><code>{'(nextState: StateModel, store: StoreApi<S>) => void'}</code></td>
|
||||
<td>No</td>
|
||||
<td>Apply a state change back to the store. Defaults to a shallow merge.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Example
|
||||
|
||||
```typescript
|
||||
import { createStore } from "zustand/vanilla";
|
||||
import { zustandStateStore } from "@json-render/zustand";
|
||||
import { StateProvider } from "@json-render/react";
|
||||
|
||||
const bearStore = createStore(() => ({
|
||||
count: 0,
|
||||
name: "Bear",
|
||||
}));
|
||||
|
||||
const store = zustandStateStore({ store: bearStore });
|
||||
```
|
||||
|
||||
```tsx
|
||||
<StateProvider store={store}>
|
||||
{/* json-render reads/writes go through Zustand */}
|
||||
</StateProvider>
|
||||
```
|
||||
|
||||
### Nested Slice
|
||||
|
||||
```typescript
|
||||
const appStore = createStore(() => ({
|
||||
ui: { count: 0 },
|
||||
auth: { token: null },
|
||||
}));
|
||||
|
||||
const store = zustandStateStore({
|
||||
store: appStore,
|
||||
selector: (s) => s.ui,
|
||||
updater: (next, s) => s.setState({ ui: next }),
|
||||
});
|
||||
```
|
||||
|
||||
## Re-exports
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Export</th>
|
||||
<th>Source</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>StateStore</code></td>
|
||||
<td><code>@json-render/core</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -341,6 +341,8 @@ February 2026
|
||||
|
||||
### New: Chat Mode (Inline GenUI)
|
||||
|
||||
> **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.
|
||||
|
||||
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.
|
||||
|
||||
```typescript
|
||||
|
||||
@@ -3,15 +3,15 @@ export const metadata = pageMetadata("docs/generation-modes")
|
||||
|
||||
# Generation Modes
|
||||
|
||||
json-render supports two modes for AI-generated UI: **Generate mode** for standalone UI and **Chat mode** for inline UI within a conversation.
|
||||
json-render supports two modes for AI-generated UI: **Standalone mode** for standalone UI and **Inline mode** for inline UI within a conversation.
|
||||
|
||||
The mode controls how the AI formats its output and how your app processes the stream. The underlying JSONL patch format is the same in both modes.
|
||||
|
||||
<GenerationModesDiagram />
|
||||
|
||||
## Generate Mode (Standalone)
|
||||
## Standalone Mode
|
||||
|
||||
In generate mode, the AI outputs **only JSONL patches** — no prose, no markdown. The entire response is a UI spec.
|
||||
In standalone mode, the AI outputs **only JSONL patches** — no prose, no markdown. The entire response is a UI spec.
|
||||
|
||||
This is the default mode and is ideal for:
|
||||
|
||||
@@ -25,7 +25,7 @@ This is the default mode and is ideal for:
|
||||
```typescript
|
||||
import { streamText } from "ai";
|
||||
|
||||
// Generate mode is the default (no mode option needed)
|
||||
// Standalone mode is the default (no mode option needed)
|
||||
const systemPrompt = catalog.prompt({
|
||||
customRules: [
|
||||
"Use Card as root for forms and small UIs.",
|
||||
@@ -74,9 +74,9 @@ The AI outputs only JSONL — one patch per line, no surrounding text:
|
||||
{"op":"add","path":"/elements/submit","value":{"type":"Button","props":{"label":"Sign In"}}}
|
||||
```
|
||||
|
||||
## Chat Mode (Inline)
|
||||
## Inline Mode
|
||||
|
||||
In chat mode, the AI responds **conversationally first**, then outputs JSONL patches on their own lines. Text-only replies are allowed when no UI is needed (e.g. greetings, clarifying questions).
|
||||
In inline mode, the AI responds **conversationally first**, then outputs JSONL patches on their own lines. Text-only replies are allowed when no UI is needed (e.g. greetings, clarifying questions).
|
||||
|
||||
This is ideal for:
|
||||
|
||||
@@ -92,8 +92,8 @@ import { streamText } from "ai";
|
||||
import { pipeJsonRender } from "@json-render/core";
|
||||
import { createUIMessageStream, createUIMessageStreamResponse } from "ai";
|
||||
|
||||
// Enable chat mode
|
||||
const systemPrompt = catalog.prompt({ mode: "chat" });
|
||||
// Enable inline mode
|
||||
const systemPrompt = catalog.prompt({ mode: "inline" });
|
||||
|
||||
const result = streamText({
|
||||
model: yourModel,
|
||||
@@ -180,8 +180,8 @@ If the user asks a simple question ("what does BTC stand for?"), the AI replies
|
||||
<thead>
|
||||
<tr>
|
||||
<th />
|
||||
<th>Generate</th>
|
||||
<th>Chat</th>
|
||||
<th>Standalone</th>
|
||||
<th>Inline</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -198,7 +198,7 @@ If the user asks a simple question ("what does BTC stand for?"), the AI replies
|
||||
<tr>
|
||||
<td>System prompt</td>
|
||||
<td><code>{"catalog.prompt()"}</code></td>
|
||||
<td><code>{'catalog.prompt({ mode: "chat" })'}</code></td>
|
||||
<td><code>{'catalog.prompt({ mode: "inline" })'}</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Stream utility</td>
|
||||
|
||||
@@ -309,10 +309,35 @@ const catalog = defineCatalog(schema, {
|
||||
|
||||
const prompt = catalog.prompt();
|
||||
|
||||
// Chat mode prompt
|
||||
// Inline mode prompt (formerly "chat")
|
||||
const inlinePrompt = catalog.prompt({ mode: "inline" });
|
||||
```
|
||||
|
||||
## Generation Modes
|
||||
|
||||
The generation mode values passed to `catalog.prompt()` have been renamed for clarity:
|
||||
|
||||
- `"generate"` is now `"standalone"`
|
||||
- `"chat"` is now `"inline"`
|
||||
|
||||
The old names are accepted as deprecated aliases, so existing code will continue to work. Update when convenient.
|
||||
|
||||
**Before:**
|
||||
|
||||
```typescript
|
||||
const prompt = catalog.prompt({ mode: "generate" });
|
||||
const chatPrompt = catalog.prompt({ mode: "chat" });
|
||||
```
|
||||
|
||||
**After:**
|
||||
|
||||
```typescript
|
||||
const prompt = catalog.prompt({ mode: "standalone" });
|
||||
const inlinePrompt = catalog.prompt({ mode: "inline" });
|
||||
```
|
||||
|
||||
The default mode (when no `mode` option is provided) is `"standalone"`, which behaves identically to the previous `"generate"` default.
|
||||
|
||||
## Validation
|
||||
|
||||
`ValidationCheck` now uses `type` instead of `fn`, `ValidationProvider` uses `customFunctions` instead of `functions`, and `useFieldValidation` takes a config object instead of a checks array.
|
||||
|
||||
@@ -91,7 +91,7 @@ The result is a native UI built from your own components — not an iframe, not
|
||||
- **[Streaming](/docs/streaming)** — Render progressively as the AI responds. Each JSONL patch adds to the spec and the UI updates in real time.
|
||||
- **[Data Binding](/docs/data-binding)** — Bind props to runtime data with `$state` paths, repeat elements over arrays, and wire two-way input bindings.
|
||||
- **[Visibility](/docs/visibility)** — Show or hide elements based on state conditions. The AI can generate conditional UIs without writing logic.
|
||||
- **[Generation Modes](/docs/generation-modes)** — Generate standalone UI (playground/builder) or inline UI within a chat conversation.
|
||||
- **[Generation Modes](/docs/generation-modes)** — Standalone mode for full-page generated UI or inline mode for UI embedded in a conversation.
|
||||
|
||||
## Next
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
import { pageMetadata } from "@/lib/page-metadata"
|
||||
|
||||
export const metadata = pageMetadata("docs/skills")
|
||||
|
||||
# Skills
|
||||
|
||||
json-render ships with skills that teach AI coding agents how to use each package. Install a skill and your agent in Cursor, Claude Code, or Codex can generate json-render UIs without manual guidance.
|
||||
|
||||
## Available Skills
|
||||
|
||||
- **core** — Core schemas, catalogs, and AI prompt generation.
|
||||
- **react** — React renderer that turns JSON specs into React component trees.
|
||||
- **react-pdf** — PDF renderer using `@react-pdf/renderer`.
|
||||
- **react-email** — Email renderer that produces HTML or plain-text emails.
|
||||
- **react-native** — React Native renderer for native mobile UIs.
|
||||
- **shadcn** — Pre-built shadcn/ui components (Radix UI + Tailwind).
|
||||
- **image** — Image renderer that turns JSON specs into SVG and PNG via Satori.
|
||||
- **remotion** — Remotion renderer for video generation from JSON timeline specs.
|
||||
- **vue** — Vue 3 renderer for Vue component trees.
|
||||
- **svelte** — Svelte 5 renderer for Svelte component trees.
|
||||
- **codegen** — Code generation utilities for building custom exporters.
|
||||
- **mcp** — MCP Apps integration for Claude, ChatGPT, Cursor, and VS Code.
|
||||
- **redux** — Redux adapter for json-render's `StateStore` interface.
|
||||
- **zustand** — Zustand adapter for json-render's `StateStore` interface.
|
||||
- **jotai** — Jotai adapter for json-render's `StateStore` interface.
|
||||
- **xstate** — XState Store adapter for json-render's `StateStore` interface.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npx skills add vercel-labs/json-render --skill core
|
||||
npx skills add vercel-labs/json-render --skill react
|
||||
npx skills add vercel-labs/json-render --skill react-pdf
|
||||
npx skills add vercel-labs/json-render --skill react-email
|
||||
npx skills add vercel-labs/json-render --skill react-native
|
||||
npx skills add vercel-labs/json-render --skill shadcn
|
||||
npx skills add vercel-labs/json-render --skill image
|
||||
npx skills add vercel-labs/json-render --skill remotion
|
||||
npx skills add vercel-labs/json-render --skill vue
|
||||
npx skills add vercel-labs/json-render --skill svelte
|
||||
npx skills add vercel-labs/json-render --skill codegen
|
||||
npx skills add vercel-labs/json-render --skill mcp
|
||||
npx skills add vercel-labs/json-render --skill redux
|
||||
npx skills add vercel-labs/json-render --skill zustand
|
||||
npx skills add vercel-labs/json-render --skill jotai
|
||||
npx skills add vercel-labs/json-render --skill xstate
|
||||
```
|
||||
|
||||
After installing, your AI agent will automatically activate the right skill when it encounters a matching request.
|
||||
|
||||
## core
|
||||
|
||||
The foundational skill. Teaches agents how to define catalogs, create schemas, build specs, and generate AI prompts. This is the starting point for any json-render project and covers `defineCatalog`, `defineSchema`, `specSchema`, `toPrompt`, and the full spec format.
|
||||
|
||||
## react
|
||||
|
||||
Teaches agents how to render JSON specs as React component trees using `JsonRender`, `JsonRenderClient`, and `useJsonRender`. Covers custom component registries, client-side interactivity, state management, and streaming integration.
|
||||
|
||||
## react-pdf
|
||||
|
||||
Teaches agents how to generate PDFs from JSON specs using `@react-pdf/renderer`. Covers the PDF-specific component registry, page layout, and styling.
|
||||
|
||||
## react-email
|
||||
|
||||
Teaches agents how to render JSON specs as HTML or plain-text emails using React Email components. Covers the email-specific registry and rendering pipeline.
|
||||
|
||||
## react-native
|
||||
|
||||
Teaches agents how to render JSON specs as native mobile UIs with React Native. Covers the native component registry and platform-specific considerations.
|
||||
|
||||
## shadcn
|
||||
|
||||
Teaches agents how to use the pre-built shadcn/ui component registry with json-render. Includes Radix UI primitives, Tailwind styling, and the full set of available shadcn components.
|
||||
|
||||
## image
|
||||
|
||||
Teaches agents how to turn JSON specs into SVG and PNG images using Satori. Covers the image-specific registry, dimensions, fonts, and rendering options.
|
||||
|
||||
## remotion
|
||||
|
||||
Teaches agents how to generate videos from JSON timeline specs using Remotion. Covers compositions, sequences, timeline structure, and video rendering.
|
||||
|
||||
## vue
|
||||
|
||||
Teaches agents how to render JSON specs as Vue 3 component trees. Covers the Vue renderer API, custom component registries, and reactivity integration.
|
||||
|
||||
## svelte
|
||||
|
||||
Teaches agents how to render JSON specs as Svelte 5 component trees. Covers the Svelte renderer API and component registration.
|
||||
|
||||
## codegen
|
||||
|
||||
Teaches agents how to use code generation utilities to export UI specs as framework-specific source code. Covers the codegen pipeline and custom exporter creation.
|
||||
|
||||
## mcp
|
||||
|
||||
Teaches agents how to build MCP Apps that serve json-render UIs inside AI tools like Claude, ChatGPT, Cursor, and VS Code. Covers MCP server setup, tool definitions, and UI streaming.
|
||||
|
||||
## redux
|
||||
|
||||
Teaches agents how to connect a Redux store to json-render's `StateStore` interface for state-driven UIs.
|
||||
|
||||
## zustand
|
||||
|
||||
Teaches agents how to connect a Zustand store to json-render's `StateStore` interface for lightweight state management.
|
||||
|
||||
## jotai
|
||||
|
||||
Teaches agents how to connect Jotai atoms to json-render's `StateStore` interface for atomic state management.
|
||||
|
||||
## xstate
|
||||
|
||||
Teaches agents how to connect an XState Store to json-render's `StateStore` interface for state-machine-driven UIs.
|
||||
|
||||
## Source
|
||||
|
||||
All skill files are in the [`skills/`](https://github.com/vercel-labs/json-render/tree/main/skills) directory of the repository.
|
||||
@@ -16,7 +16,8 @@ const SYSTEM_PROMPT = `You are a helpful documentation assistant for json-render
|
||||
|
||||
GitHub repository: https://github.com/vercel-labs/json-render
|
||||
Documentation: https://json-render.dev/docs
|
||||
npm packages: @json-render/core, @json-render/react, @json-render/react-email, @json-render/react-pdf, @json-render/image, @json-render/remotion, @json-render/codegen, @json-render/mcp
|
||||
npm packages: @json-render/core, @json-render/react, @json-render/vue, @json-render/svelte, @json-render/shadcn, @json-render/react-native, @json-render/react-email, @json-render/react-pdf, @json-render/image, @json-render/remotion, @json-render/codegen, @json-render/mcp, @json-render/redux, @json-render/zustand, @json-render/jotai, @json-render/xstate
|
||||
Skills: json-render ships AI agent skills that teach coding agents how to use each package. Install with "npx skills add vercel-labs/json-render --skill <name>". Available skills: core, react, react-pdf, react-email, react-native, shadcn, image, remotion, vue, svelte, codegen, mcp, redux, zustand, jotai, xstate. See /docs/skills for details.
|
||||
|
||||
You have access to the full json-render documentation via the bash and readFile tools. The docs are available as markdown files in the /workspace/docs/ directory.
|
||||
|
||||
|
||||
@@ -19,11 +19,11 @@ function FormUI() {
|
||||
);
|
||||
}
|
||||
|
||||
function ChatModeDiagram() {
|
||||
function InlineModeDiagram() {
|
||||
return (
|
||||
<div className="flex flex-col h-full">
|
||||
<div className="text-xs font-medium text-muted-foreground mb-3 text-center">
|
||||
Chat Mode
|
||||
Inline Mode
|
||||
</div>
|
||||
<div className="flex-1 border border-border rounded-lg bg-background overflow-hidden flex flex-col">
|
||||
{/* Chat area */}
|
||||
@@ -69,11 +69,11 @@ function ChatModeDiagram() {
|
||||
);
|
||||
}
|
||||
|
||||
function GenerateModeDiagram() {
|
||||
function StandaloneModeDiagram() {
|
||||
return (
|
||||
<div className="flex flex-col h-full">
|
||||
<div className="text-xs font-medium text-muted-foreground mb-3 text-center">
|
||||
Generate Mode
|
||||
Standalone Mode
|
||||
</div>
|
||||
<div className="flex-1 border border-border rounded-lg bg-background overflow-hidden flex flex-row">
|
||||
{/* Left panel - prompt */}
|
||||
@@ -104,10 +104,10 @@ export function GenerationModesDiagram() {
|
||||
<div className="not-prose my-8">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
|
||||
<div className="h-[280px]">
|
||||
<ChatModeDiagram />
|
||||
<InlineModeDiagram />
|
||||
</div>
|
||||
<div className="h-[280px]">
|
||||
<GenerateModeDiagram />
|
||||
<StandaloneModeDiagram />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,7 @@ export const docsNavigation: NavSection[] = [
|
||||
{ title: "Introduction", href: "/docs" },
|
||||
{ title: "Installation", href: "/docs/installation" },
|
||||
{ title: "Quick Start", href: "/docs/quick-start" },
|
||||
{ title: "Skills", href: "/docs/skills" },
|
||||
{ title: "Migration Guide", href: "/docs/migration" },
|
||||
{ title: "Changelog", href: "/docs/changelog" },
|
||||
],
|
||||
@@ -134,6 +135,10 @@ export const docsNavigation: NavSection[] = [
|
||||
{ title: "@json-render/svelte", href: "/docs/api/svelte" },
|
||||
{ title: "@json-render/codegen", href: "/docs/api/codegen" },
|
||||
{ title: "@json-render/mcp", href: "/docs/api/mcp" },
|
||||
{ title: "@json-render/redux", href: "/docs/api/redux" },
|
||||
{ title: "@json-render/zustand", href: "/docs/api/zustand" },
|
||||
{ title: "@json-render/jotai", href: "/docs/api/jotai" },
|
||||
{ title: "@json-render/xstate", href: "/docs/api/xstate" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -37,6 +37,7 @@ export const PAGE_TITLES: Record<string, string> = {
|
||||
"docs/ag-ui": "AG-UI Integration",
|
||||
"docs/migration": "Migration Guide",
|
||||
"docs/changelog": "Changelog",
|
||||
"docs/skills": "Skills",
|
||||
|
||||
// API references
|
||||
"docs/api/core": "@json-render/core API",
|
||||
@@ -51,6 +52,10 @@ export const PAGE_TITLES: Record<string, string> = {
|
||||
"docs/api/remotion": "@json-render/remotion API",
|
||||
"docs/api/shadcn": "@json-render/shadcn API",
|
||||
"docs/api/mcp": "@json-render/mcp API",
|
||||
"docs/api/redux": "@json-render/redux API",
|
||||
"docs/api/zustand": "@json-render/zustand API",
|
||||
"docs/api/jotai": "@json-render/jotai API",
|
||||
"docs/api/xstate": "@json-render/xstate API",
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "web",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.6",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# example-chat
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/react@0.12.1
|
||||
- @json-render/shadcn@0.12.1
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/react@0.12.0
|
||||
- @json-render/shadcn@0.12.0
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -130,7 +130,7 @@ When the user asks for a quiz, test, or Q&A, build an interactive experience:
|
||||
4. You can also add a final score section that becomes visible when all questions are submitted.
|
||||
|
||||
${explorerCatalog.prompt({
|
||||
mode: "chat",
|
||||
mode: "inline",
|
||||
customRules: [
|
||||
"NEVER use viewport height classes (min-h-screen, h-screen) — the UI renders inside a fixed-size container.",
|
||||
"Prefer Grid with columns='2' or columns='3' for side-by-side layouts.",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-chat",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.6",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# example-dashboard
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/codegen@0.12.1
|
||||
- @json-render/react@0.12.1
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/codegen@0.12.0
|
||||
- @json-render/react@0.12.0
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-dashboard",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.6",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# example-image
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/image@0.12.1
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/image@0.12.0
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-image",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.3",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# example-mcp
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/mcp@0.12.1
|
||||
- @json-render/react@0.12.1
|
||||
- @json-render/shadcn@0.12.1
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/mcp@0.12.0
|
||||
- @json-render/react@0.12.0
|
||||
- @json-render/shadcn@0.12.0
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-mcp",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.2",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -16,8 +16,8 @@
|
||||
"@json-render/shadcn": "workspace:*",
|
||||
"@modelcontextprotocol/ext-apps": "^1.2.0",
|
||||
"@modelcontextprotocol/sdk": "^1.27.1",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -5,6 +5,9 @@ import tailwindcss from "@tailwindcss/vite";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react(), tailwindcss(), viteSingleFile()],
|
||||
resolve: {
|
||||
dedupe: ["react", "react-dom"],
|
||||
},
|
||||
build: {
|
||||
outDir: "dist",
|
||||
emptyOutDir: false,
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# example-no-ai
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/react@0.12.1
|
||||
- @json-render/shadcn@0.12.1
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/react@0.12.0
|
||||
- @json-render/shadcn@0.12.0
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-no-ai",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.6",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# example-react-email
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/react-email@0.12.1
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/react-email@0.12.0
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-react-email",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.2",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# example-react-native
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/react-native@0.12.1
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/react-native@0.12.0
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-react-native",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.6",
|
||||
"private": true,
|
||||
"main": "expo-router/entry",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# example-react-pdf
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/react-pdf@0.12.1
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/react-pdf@0.12.0
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-react-pdf",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.6",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# example-remotion
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/remotion@0.12.1
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/remotion@0.12.0
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-remotion",
|
||||
"version": "0.1.4",
|
||||
"version": "0.1.6",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
import "./.next/dev/types/routes.d.ts";
|
||||
import "./.next/types/routes.d.ts";
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# com.example.json-render-demo
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/react@0.12.1
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/react@0.12.0
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "com.example.json-render-demo",
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.7",
|
||||
"description": "Test",
|
||||
"private": true,
|
||||
"license": "~~proprietary~~",
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# com.example.json-render-fullpage-demo
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/react@0.12.1
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/react@0.12.0
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "com.example.json-render-fullpage-demo",
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.7",
|
||||
"description": "Full-page Stripe App example (alpha)",
|
||||
"private": true,
|
||||
"license": "~~proprietary~~",
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# svelte-chat
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/svelte@0.12.1
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/svelte@0.12.0
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "svelte-chat",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
|
||||
@@ -62,7 +62,7 @@ INPUT COMPONENTS:
|
||||
- Button: Clickable button. Use on.press to trigger actions.
|
||||
|
||||
${explorerCatalog.prompt({
|
||||
mode: "chat",
|
||||
mode: "inline",
|
||||
customRules: [
|
||||
"NEVER use viewport height classes (min-h-screen, h-screen) — the UI renders inside a fixed-size container.",
|
||||
"Prefer Grid with columns='2' or columns='3' for side-by-side layouts.",
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# example-svelte
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/svelte@0.12.1
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/svelte@0.12.0
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-svelte",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# vite-renderers
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/react@0.12.1
|
||||
- @json-render/svelte@0.12.1
|
||||
- @json-render/vue@0.12.1
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/svelte@0.12.0
|
||||
- @json-render/react@0.12.0
|
||||
- @json-render/vue@0.12.0
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vite-renderers",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.4",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# example-vue
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/vue@0.12.1
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/vue@0.12.0
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-vue",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.4",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"predev": "command -v portless >/dev/null 2>&1 || (echo '\\nportless is required but not installed. Run: npm i -g portless\\nSee: https://github.com/vercel-labs/portless\\n' && exit 1)",
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @json-render/codegen
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/codegen",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Utilities for generating code from json-render UI trees",
|
||||
"keywords": [
|
||||
@@ -15,7 +15,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/codegen"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# @json-render/core
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 54a1ecf: Rename generation modes and fix MCP React duplicate module error.
|
||||
|
||||
### Changed:
|
||||
- **`@json-render/core`** — Renamed generation modes from `"generate"` / `"chat"` to `"standalone"` / `"inline"`. The old names still work but emit a deprecation warning.
|
||||
|
||||
### Fixed:
|
||||
- **`@json-render/mcp`** — Resolved React duplicate module error (`useRef` returning null) by adding `resolve.dedupe` Vite configuration. Added `./build-app-html` export entry point.
|
||||
|
||||
### Other:
|
||||
- Updated `homepage` URLs across all packages to point to `https://json-render.dev`.
|
||||
- Reorganized skills directory structure for cleaner naming.
|
||||
- Added skills documentation page to the web app.
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 63c339b: Add Svelte renderer, React Email renderer, and MCP Apps integration.
|
||||
|
||||
### New:
|
||||
- **`@json-render/svelte`** — 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.
|
||||
- **`@json-render/react-email`** — 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. Custom catalog and registry support.
|
||||
- **`@json-render/mcp`** — 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.
|
||||
|
||||
### Fixed:
|
||||
- **`@json-render/svelte`** — Corrected JSDoc comment and added missing `zod` peer dependency.
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -227,7 +227,7 @@ Schema options:
|
||||
| `ActionBinding` | Action binding with `action`, `params`, `confirm`, `preventDefault`, etc. |
|
||||
| `BuiltInAction` | Built-in action definition with `name` and `description` |
|
||||
|
||||
### Chat Mode (Mixed Streams)
|
||||
### Inline Mode (Mixed Streams)
|
||||
|
||||
| Export | Purpose |
|
||||
|--------|---------|
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/core",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "JSON becomes real things. Define your catalog, register your components, let AI generate.",
|
||||
"keywords": [
|
||||
@@ -19,7 +19,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/core"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -257,7 +257,7 @@ describe("catalog.prompt", () => {
|
||||
expect(prompt).toContain("Keep UIs simple");
|
||||
});
|
||||
|
||||
it("generates chat mode prompt when mode is chat", () => {
|
||||
it("generates inline mode prompt when mode is inline", () => {
|
||||
const catalog = defineCatalog(testSchema, {
|
||||
components: {
|
||||
Text: {
|
||||
@@ -268,13 +268,13 @@ describe("catalog.prompt", () => {
|
||||
},
|
||||
actions: {},
|
||||
});
|
||||
const prompt = catalog.prompt({ mode: "chat" });
|
||||
const prompt = catalog.prompt({ mode: "inline" });
|
||||
expect(prompt).toContain("```spec");
|
||||
expect(prompt).toContain("conversationally");
|
||||
expect(prompt).toContain("text + JSONL");
|
||||
});
|
||||
|
||||
it("generates generate mode prompt by default", () => {
|
||||
it("generates standalone mode prompt by default", () => {
|
||||
const catalog = defineCatalog(testSchema, {
|
||||
components: {
|
||||
Text: {
|
||||
@@ -290,6 +290,38 @@ describe("catalog.prompt", () => {
|
||||
expect(prompt).not.toContain("conversationally");
|
||||
});
|
||||
|
||||
it("accepts deprecated 'chat' as alias for 'inline'", () => {
|
||||
const catalog = defineCatalog(testSchema, {
|
||||
components: {
|
||||
Text: {
|
||||
props: z.object({}),
|
||||
description: "",
|
||||
slots: [],
|
||||
},
|
||||
},
|
||||
actions: {},
|
||||
});
|
||||
const inlinePrompt = catalog.prompt({ mode: "inline" });
|
||||
const chatPrompt = catalog.prompt({ mode: "chat" });
|
||||
expect(chatPrompt).toEqual(inlinePrompt);
|
||||
});
|
||||
|
||||
it("accepts deprecated 'generate' as alias for 'standalone'", () => {
|
||||
const catalog = defineCatalog(testSchema, {
|
||||
components: {
|
||||
Text: {
|
||||
props: z.object({}),
|
||||
description: "",
|
||||
slots: [],
|
||||
},
|
||||
},
|
||||
actions: {},
|
||||
});
|
||||
const standalonePrompt = catalog.prompt({ mode: "standalone" });
|
||||
const generatePrompt = catalog.prompt({ mode: "generate" });
|
||||
expect(generatePrompt).toEqual(standalonePrompt);
|
||||
});
|
||||
|
||||
it("uses actual catalog component names in examples", () => {
|
||||
const catalog = defineCatalog(testSchema, {
|
||||
components: {
|
||||
|
||||
@@ -112,11 +112,14 @@ export interface PromptOptions {
|
||||
/**
|
||||
* Output mode for the generated prompt.
|
||||
*
|
||||
* - `"generate"` (default): The LLM should output only JSONL patches (no prose).
|
||||
* - `"chat"`: The LLM should respond conversationally first, then output JSONL patches.
|
||||
* - `"standalone"` (default): The LLM should output only JSONL patches (no prose).
|
||||
* - `"inline"`: The LLM should respond conversationally first, then output JSONL patches.
|
||||
* Includes rules about interleaving text with JSONL and not wrapping in code fences.
|
||||
*
|
||||
* @deprecated `"generate"` — use `"standalone"` instead.
|
||||
* @deprecated `"chat"` — use `"inline"` instead.
|
||||
*/
|
||||
mode?: "generate" | "chat";
|
||||
mode?: "standalone" | "inline" | "generate" | "chat";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -563,15 +566,28 @@ function generatePrompt<TDef extends SchemaDefinition, TCatalog>(
|
||||
const {
|
||||
system = "You are a UI generator that outputs JSON.",
|
||||
customRules = [],
|
||||
mode = "generate",
|
||||
mode: rawMode = "standalone",
|
||||
} = options;
|
||||
|
||||
const mode: "standalone" | "inline" =
|
||||
rawMode === "chat"
|
||||
? (console.warn(
|
||||
'[json-render] mode "chat" is deprecated, use "inline" instead',
|
||||
),
|
||||
"inline")
|
||||
: rawMode === "generate"
|
||||
? (console.warn(
|
||||
'[json-render] mode "generate" is deprecated, use "standalone" instead',
|
||||
),
|
||||
"standalone")
|
||||
: rawMode;
|
||||
|
||||
const lines: string[] = [];
|
||||
lines.push(system);
|
||||
lines.push("");
|
||||
|
||||
// Output format section - explain JSONL streaming patch format
|
||||
if (mode === "chat") {
|
||||
if (mode === "inline") {
|
||||
lines.push("OUTPUT FORMAT (text + JSONL, RFC 6902 JSON Patch):");
|
||||
lines.push(
|
||||
"You respond conversationally. When generating UI, first write a brief explanation (1-3 sentences), then output JSONL patch lines wrapped in a ```spec code fence.",
|
||||
@@ -1014,7 +1030,7 @@ Note: state patches appear right after the elements that use them, so the UI fil
|
||||
// Rules
|
||||
lines.push("RULES:");
|
||||
const baseRules =
|
||||
mode === "chat"
|
||||
mode === "inline"
|
||||
? [
|
||||
"When generating UI, wrap all JSONL patches in a ```spec code fence - one JSON object per line inside the fence",
|
||||
"Write a brief conversational response before any JSONL output",
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @json-render/image
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/image",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Image renderer for @json-render/core. JSON becomes SVG and PNG images via Satori.",
|
||||
"keywords": [
|
||||
@@ -20,7 +20,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/image"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @json-render/jotai
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/jotai",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Jotai adapter for json-render StateStore",
|
||||
"keywords": [
|
||||
@@ -14,7 +14,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/jotai"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# @json-render/mcp
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 54a1ecf: Rename generation modes and fix MCP React duplicate module error.
|
||||
|
||||
### Changed:
|
||||
- **`@json-render/core`** — Renamed generation modes from `"generate"` / `"chat"` to `"standalone"` / `"inline"`. The old names still work but emit a deprecation warning.
|
||||
|
||||
### Fixed:
|
||||
- **`@json-render/mcp`** — Resolved React duplicate module error (`useRef` returning null) by adding `resolve.dedupe` Vite configuration. Added `./build-app-html` export entry point.
|
||||
|
||||
### Other:
|
||||
- Updated `homepage` URLs across all packages to point to `https://json-render.dev`.
|
||||
- Reorganized skills directory structure for cleaner naming.
|
||||
- Added skills documentation page to the web app.
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 63c339b: Add Svelte renderer, React Email renderer, and MCP Apps integration.
|
||||
|
||||
### New:
|
||||
- **`@json-render/svelte`** — 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.
|
||||
- **`@json-render/react-email`** — 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. Custom catalog and registry support.
|
||||
- **`@json-render/mcp`** — 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.
|
||||
|
||||
### Fixed:
|
||||
- **`@json-render/svelte`** — Corrected JSDoc comment and added missing `zod` peer dependency.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/mcp",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "MCP Apps integration for @json-render/core. Serve json-render UIs as interactive MCP Apps in Claude, ChatGPT, Cursor, and VS Code.",
|
||||
"keywords": [
|
||||
@@ -22,7 +22,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/mcp"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
@@ -42,6 +42,11 @@
|
||||
"types": "./dist/app.d.ts",
|
||||
"import": "./dist/app.mjs",
|
||||
"require": "./dist/app.js"
|
||||
},
|
||||
"./build-app-html": {
|
||||
"types": "./dist/build-app-html-entry.d.ts",
|
||||
"import": "./dist/build-app-html-entry.mjs",
|
||||
"require": "./dist/build-app-html-entry.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Server-side utility for building self-contained MCP App HTML.
|
||||
*
|
||||
* This entry point does NOT depend on React and is safe to import
|
||||
* in Node.js / server environments.
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
export { buildAppHtml } from "./build-app-html.js";
|
||||
export type { BuildAppHtmlOptions } from "./build-app-html.js";
|
||||
@@ -1,7 +1,7 @@
|
||||
import { defineConfig } from "tsup";
|
||||
|
||||
export default defineConfig({
|
||||
entry: ["src/index.ts", "src/app.ts"],
|
||||
entry: ["src/index.ts", "src/app.ts", "src/build-app-html-entry.ts"],
|
||||
format: ["cjs", "esm"],
|
||||
dts: true,
|
||||
sourcemap: true,
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# @json-render/react-email
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 63c339b: Add Svelte renderer, React Email renderer, and MCP Apps integration.
|
||||
|
||||
### New:
|
||||
- **`@json-render/svelte`** — 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.
|
||||
- **`@json-render/react-email`** — 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. Custom catalog and registry support.
|
||||
- **`@json-render/mcp`** — 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.
|
||||
|
||||
### Fixed:
|
||||
- **`@json-render/svelte`** — Corrected JSDoc comment and added missing `zod` peer dependency.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/react-email",
|
||||
"version": "0.8.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "React Email renderer for @json-render/core. JSON becomes HTML emails.",
|
||||
"keywords": [
|
||||
@@ -18,7 +18,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/react-email"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @json-render/react-native
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/react-native",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "React Native renderer for @json-render/core. JSON becomes React Native components.",
|
||||
"keywords": [
|
||||
@@ -19,7 +19,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/react-native"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @json-render/react-pdf
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/react-pdf",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "React PDF renderer for @json-render/core. JSON becomes PDF documents.",
|
||||
"keywords": [
|
||||
@@ -18,7 +18,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/react-pdf"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @internal/react-state
|
||||
|
||||
## 0.8.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.8.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.8.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@internal/react-state",
|
||||
"version": "0.8.4",
|
||||
"version": "0.8.6",
|
||||
"private": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "Shared React state context for json-render renderer packages",
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @json-render/react
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/react",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "React renderer for @json-render/core. JSON becomes React components.",
|
||||
"keywords": [
|
||||
@@ -19,7 +19,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/react"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @json-render/redux
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/redux",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Redux adapter for json-render StateStore",
|
||||
"keywords": [
|
||||
@@ -14,7 +14,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/redux"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @json-render/remotion
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/remotion",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Remotion renderer for @json-render/core. JSON becomes video compositions.",
|
||||
"keywords": [
|
||||
@@ -19,7 +19,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/remotion"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @json-render/shadcn
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
- @json-render/react@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
- @json-render/react@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/shadcn",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "shadcn/ui component library for @json-render/core. JSON becomes beautiful Tailwind-styled React components.",
|
||||
"keywords": [
|
||||
@@ -22,7 +22,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/shadcn"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# @json-render/svelte
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 63c339b: Add Svelte renderer, React Email renderer, and MCP Apps integration.
|
||||
|
||||
### New:
|
||||
- **`@json-render/svelte`** — 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.
|
||||
- **`@json-render/react-email`** — 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. Custom catalog and registry support.
|
||||
- **`@json-render/mcp`** — 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.
|
||||
|
||||
### Fixed:
|
||||
- **`@json-render/svelte`** — Corrected JSDoc comment and added missing `zod` peer dependency.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
@@ -0,0 +1,155 @@
|
||||
# @json-render/svelte
|
||||
|
||||
Svelte 5 renderer for `@json-render/core`. Turn JSON specs into Svelte components with runes-based reactivity.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @json-render/core @json-render/svelte
|
||||
```
|
||||
|
||||
Peer dependencies: `svelte ^5.0.0` and `zod ^4.0.0`.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Create a Catalog
|
||||
|
||||
```typescript
|
||||
import { defineCatalog } from "@json-render/core";
|
||||
import { schema } from "@json-render/svelte/schema";
|
||||
import { z } from "zod";
|
||||
|
||||
export const catalog = defineCatalog(schema, {
|
||||
components: {
|
||||
Card: {
|
||||
props: z.object({
|
||||
title: z.string(),
|
||||
description: z.string().nullable(),
|
||||
}),
|
||||
description: "A card container",
|
||||
},
|
||||
Button: {
|
||||
props: z.object({
|
||||
label: z.string(),
|
||||
action: z.string(),
|
||||
}),
|
||||
description: "A clickable button",
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
submit: { description: "Submit the form" },
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### 2. Define Component Implementations
|
||||
|
||||
```typescript
|
||||
import { defineRegistry } from "@json-render/svelte";
|
||||
import { catalog } from "./catalog";
|
||||
|
||||
export const { registry } = defineRegistry(catalog, {
|
||||
components: {
|
||||
Card: ({ props, children }) => /* Svelte 5 snippet */,
|
||||
Button: ({ props, emit }) => /* Svelte 5 snippet */,
|
||||
},
|
||||
actions: {
|
||||
submit: async (params) => { /* handle submit */ },
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Render Specs
|
||||
|
||||
```svelte
|
||||
<script>
|
||||
import { Renderer, StateProvider, ActionProvider } from "@json-render/svelte";
|
||||
import { registry } from "./registry";
|
||||
|
||||
const spec = { /* ... */ };
|
||||
</script>
|
||||
|
||||
<StateProvider initialState={{ form: { name: "" } }}>
|
||||
<ActionProvider handlers={{ submit: handleSubmit }}>
|
||||
<Renderer {spec} {registry} />
|
||||
</ActionProvider>
|
||||
</StateProvider>
|
||||
```
|
||||
|
||||
## Providers
|
||||
|
||||
| Provider | Purpose |
|
||||
|----------|---------|
|
||||
| `StateProvider` | Share state across components (JSON Pointer paths). Accepts optional `store` prop for controlled mode. |
|
||||
| `ActionProvider` | Handle actions dispatched via the event system |
|
||||
| `VisibilityProvider` | Enable conditional rendering based on state |
|
||||
| `ValidationProvider` | Form field validation |
|
||||
| `RepeatScopeProvider` | Repeat scope for list rendering |
|
||||
| `FunctionsContextProvider` | Register `$computed` functions |
|
||||
| `JsonUIProvider` | All-in-one provider combining state, actions, visibility, validation, and functions |
|
||||
|
||||
## Context Accessors
|
||||
|
||||
Svelte 5 uses `getContext`-based accessors instead of hooks:
|
||||
|
||||
| Accessor | Purpose |
|
||||
|----------|---------|
|
||||
| `getStateContext()` | Access state context (`state`, `get`, `set`) |
|
||||
| `getStateValue(path)` | Get single value from state |
|
||||
| `getBoundProp(value, binding)` | Two-way binding for `$bindState`/`$bindItem` |
|
||||
| `getVisibilityContext()` | Access visibility context |
|
||||
| `isVisible(condition)` | Check if a visibility condition is met |
|
||||
| `getActionContext()` | Access action context |
|
||||
| `getAction(binding)` | Get a single action dispatch function |
|
||||
| `getValidationContext()` | Access validation context |
|
||||
| `getFieldValidation(path, config)` | Field validation state |
|
||||
| `getRepeatScope()` | Access current repeat scope |
|
||||
| `getFunctions()` | Access registered computed functions |
|
||||
|
||||
## Streaming
|
||||
|
||||
```typescript
|
||||
import { createUIStream, createChatUI } from "@json-render/svelte";
|
||||
|
||||
const stream = createUIStream({ endpoint: "/api/generate" });
|
||||
|
||||
// Or for chat-style UI:
|
||||
const chat = createChatUI({ endpoint: "/api/chat" });
|
||||
```
|
||||
|
||||
## Key Exports
|
||||
|
||||
| Export | Purpose |
|
||||
|--------|---------|
|
||||
| `defineRegistry` | Create a type-safe component registry from a catalog |
|
||||
| `createRenderer` | Create a renderer function from a registry |
|
||||
| `Renderer` | Render a spec using a registry |
|
||||
| `CatalogRenderer` | Render with automatic provider wiring |
|
||||
| `JsonUIProvider` | All-in-one provider |
|
||||
| `schema` | Element tree schema (includes built-in state actions) |
|
||||
| `createUIStream` | Stream specs from an API endpoint |
|
||||
| `createChatUI` | Chat-style streaming interface |
|
||||
| `flatToTree` | Convert flat spec to tree format |
|
||||
| `ConfirmDialog` | Confirmation dialog component |
|
||||
| `ConfirmDialogManager` | Manage multiple confirmation dialogs |
|
||||
|
||||
### Types
|
||||
|
||||
| Export | Purpose |
|
||||
|--------|---------|
|
||||
| `ComponentContext` | Typed component render function context (catalog-aware) |
|
||||
| `BaseComponentProps` | Catalog-agnostic base type for reusable component libraries |
|
||||
| `EventHandle` | Event handle with `emit()`, `shouldPreventDefault`, `bound` |
|
||||
| `ComponentFn` | Component render function type |
|
||||
| `SetState` | State setter type |
|
||||
| `StateModel` | State model type |
|
||||
| `SvelteSchema` | Schema type for the Svelte renderer |
|
||||
| `SvelteSpec` | Spec type for the Svelte renderer |
|
||||
|
||||
## Documentation
|
||||
|
||||
Full API reference: [json-render.dev/docs/api/svelte](https://json-render.dev/docs/api/svelte).
|
||||
|
||||
## License
|
||||
|
||||
Apache-2.0
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/svelte",
|
||||
"version": "0.6.1",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Svelte 5 renderer for @json-render/core. JSON becomes Svelte components.",
|
||||
"keywords": [
|
||||
@@ -21,7 +21,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/svelte"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @json-render/vue
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/vue",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Vue renderer for @json-render/core. JSON becomes Vue components.",
|
||||
"keywords": [
|
||||
@@ -19,7 +19,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/vue"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @json-render/xstate
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/xstate",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "XState Store adapter for json-render StateStore",
|
||||
"keywords": [
|
||||
@@ -15,7 +15,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/xstate"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @json-render/zustand
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [54a1ecf]
|
||||
- @json-render/core@0.12.1
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [63c339b]
|
||||
- @json-render/core@0.12.0
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@json-render/zustand",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.1",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Zustand adapter for json-render StateStore",
|
||||
"keywords": [
|
||||
@@ -14,7 +14,7 @@
|
||||
"url": "git+https://github.com/vercel-labs/json-render.git",
|
||||
"directory": "packages/zustand"
|
||||
},
|
||||
"homepage": "https://github.com/vercel-labs/json-render#readme",
|
||||
"homepage": "https://json-render.dev",
|
||||
"bugs": {
|
||||
"url": "https://github.com/vercel-labs/json-render/issues"
|
||||
},
|
||||
|
||||
Generated
+9
-48
@@ -536,16 +536,16 @@ importers:
|
||||
version: link:../../packages/shadcn
|
||||
'@modelcontextprotocol/ext-apps':
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(zod@4.3.6)
|
||||
version: 1.2.0(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6)
|
||||
'@modelcontextprotocol/sdk':
|
||||
specifier: ^1.27.1
|
||||
version: 1.27.1(zod@4.3.6)
|
||||
react:
|
||||
specifier: 19.2.3
|
||||
version: 19.2.3
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.4
|
||||
react-dom:
|
||||
specifier: 19.2.3
|
||||
version: 19.2.3(react@19.2.3)
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.4(react@19.2.4)
|
||||
zod:
|
||||
specifier: ^4.3.6
|
||||
version: 4.3.6
|
||||
@@ -600,7 +600,7 @@ importers:
|
||||
version: 0.563.0(react@19.2.4)
|
||||
next:
|
||||
specifier: 16.1.6
|
||||
version: 16.1.6(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
version: 16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
radix-ui:
|
||||
specifier: ^1.4.3
|
||||
version: 1.4.3(@types/react-dom@19.2.3(@types/react@19.2.3))(@types/react@19.2.3)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
@@ -947,7 +947,7 @@ importers:
|
||||
version: 6.0.103(zod@4.3.6)
|
||||
next:
|
||||
specifier: ^16.1.6
|
||||
version: 16.1.6(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
version: 16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
react:
|
||||
specifier: ^19.1.0
|
||||
version: 19.2.4
|
||||
@@ -15019,14 +15019,6 @@ snapshots:
|
||||
|
||||
'@mixmark-io/domino@2.2.0': {}
|
||||
|
||||
'@modelcontextprotocol/ext-apps@1.2.0(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(zod@4.3.6)':
|
||||
dependencies:
|
||||
'@modelcontextprotocol/sdk': 1.27.1(zod@4.3.6)
|
||||
zod: 4.3.6
|
||||
optionalDependencies:
|
||||
react: 19.2.3
|
||||
react-dom: 19.2.3(react@19.2.3)
|
||||
|
||||
'@modelcontextprotocol/ext-apps@1.2.0(@modelcontextprotocol/sdk@1.27.1(zod@4.3.6))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod@4.3.6)':
|
||||
dependencies:
|
||||
'@modelcontextprotocol/sdk': 1.27.1(zod@4.3.6)
|
||||
@@ -17941,7 +17933,7 @@ snapshots:
|
||||
'@stripe/ui-extension-tools@0.0.1(@babel/core@7.29.0)(babel-jest@27.5.1(@babel/core@7.29.0))':
|
||||
dependencies:
|
||||
'@types/jest': 28.1.8
|
||||
'@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.2(jiti@2.6.1))(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)
|
||||
'@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)
|
||||
'@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5)
|
||||
eslint: 8.57.1
|
||||
eslint-plugin-react: 7.37.5(eslint@8.57.1)
|
||||
@@ -18467,7 +18459,7 @@ snapshots:
|
||||
'@types/node': 22.19.6
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.2(jiti@2.6.1))(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)':
|
||||
'@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
'@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5)
|
||||
@@ -23804,32 +23796,6 @@ snapshots:
|
||||
- '@babel/core'
|
||||
- babel-plugin-macros
|
||||
|
||||
next@16.1.6(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
|
||||
dependencies:
|
||||
'@next/env': 16.1.6
|
||||
'@swc/helpers': 0.5.15
|
||||
baseline-browser-mapping: 2.9.14
|
||||
caniuse-lite: 1.0.30001764
|
||||
postcss: 8.4.31
|
||||
react: 19.2.4
|
||||
react-dom: 19.2.4(react@19.2.4)
|
||||
styled-jsx: 5.1.6(react@19.2.4)
|
||||
optionalDependencies:
|
||||
'@next/swc-darwin-arm64': 16.1.6
|
||||
'@next/swc-darwin-x64': 16.1.6
|
||||
'@next/swc-linux-arm64-gnu': 16.1.6
|
||||
'@next/swc-linux-arm64-musl': 16.1.6
|
||||
'@next/swc-linux-x64-gnu': 16.1.6
|
||||
'@next/swc-linux-x64-musl': 16.1.6
|
||||
'@next/swc-win32-arm64-msvc': 16.1.6
|
||||
'@next/swc-win32-x64-msvc': 16.1.6
|
||||
'@opentelemetry/api': 1.9.0
|
||||
babel-plugin-react-compiler: 1.0.0
|
||||
sharp: 0.34.5
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- babel-plugin-macros
|
||||
|
||||
node-abi@3.87.0:
|
||||
dependencies:
|
||||
semver: 7.7.3
|
||||
@@ -25904,11 +25870,6 @@ snapshots:
|
||||
client-only: 0.0.1
|
||||
react: 19.2.3
|
||||
|
||||
styled-jsx@5.1.6(react@19.2.4):
|
||||
dependencies:
|
||||
client-only: 0.0.1
|
||||
react: 19.2.4
|
||||
|
||||
sucrase@3.35.1:
|
||||
dependencies:
|
||||
'@jridgewell/gen-mapping': 0.3.13
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
name: codegen
|
||||
description: Code generation utilities for json-render. Use when generating code from UI specs, building custom code exporters, traversing specs, or serializing props for @json-render/codegen.
|
||||
---
|
||||
|
||||
# @json-render/codegen
|
||||
|
||||
Framework-agnostic utilities for generating code from json-render UI trees. Use these to build custom code exporters for Next.js, Remix, or other frameworks.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @json-render/codegen
|
||||
```
|
||||
|
||||
## Tree Traversal
|
||||
|
||||
```typescript
|
||||
import {
|
||||
traverseSpec,
|
||||
collectUsedComponents,
|
||||
collectStatePaths,
|
||||
collectActions,
|
||||
} from "@json-render/codegen";
|
||||
|
||||
// Walk the spec depth-first
|
||||
traverseSpec(spec, (element, key, depth, parent) => {
|
||||
console.log(`${" ".repeat(depth * 2)}${key}: ${element.type}`);
|
||||
});
|
||||
|
||||
// Get all component types used
|
||||
const components = collectUsedComponents(spec);
|
||||
// Set { "Card", "Metric", "Button" }
|
||||
|
||||
// Get all state paths referenced
|
||||
const statePaths = collectStatePaths(spec);
|
||||
// Set { "analytics/revenue", "user/name" }
|
||||
|
||||
// Get all action names
|
||||
const actions = collectActions(spec);
|
||||
// Set { "submit_form", "refresh_data" }
|
||||
```
|
||||
|
||||
## Serialization
|
||||
|
||||
```typescript
|
||||
import {
|
||||
serializePropValue,
|
||||
serializeProps,
|
||||
escapeString,
|
||||
type SerializeOptions,
|
||||
} from "@json-render/codegen";
|
||||
|
||||
// Serialize a single value
|
||||
serializePropValue("hello");
|
||||
// { value: '"hello"', needsBraces: false }
|
||||
|
||||
serializePropValue({ $state: "/user/name" });
|
||||
// { value: '{ $state: "/user/name" }', needsBraces: true }
|
||||
|
||||
// Serialize props for JSX
|
||||
serializeProps({ title: "Dashboard", columns: 3, disabled: true });
|
||||
// 'title="Dashboard" columns={3} disabled'
|
||||
|
||||
// Escape strings for code
|
||||
escapeString('hello "world"');
|
||||
// 'hello \"world\"'
|
||||
```
|
||||
|
||||
### SerializeOptions
|
||||
|
||||
```typescript
|
||||
interface SerializeOptions {
|
||||
quotes?: "single" | "double";
|
||||
indent?: number;
|
||||
}
|
||||
```
|
||||
|
||||
## Types
|
||||
|
||||
```typescript
|
||||
import type { GeneratedFile, CodeGenerator } from "@json-render/codegen";
|
||||
|
||||
const myGenerator: CodeGenerator = {
|
||||
generate(spec) {
|
||||
return [
|
||||
{ path: "package.json", content: "..." },
|
||||
{ path: "app/page.tsx", content: "..." },
|
||||
];
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Building a Custom Generator
|
||||
|
||||
```typescript
|
||||
import {
|
||||
collectUsedComponents,
|
||||
collectStatePaths,
|
||||
traverseSpec,
|
||||
serializeProps,
|
||||
type GeneratedFile,
|
||||
} from "@json-render/codegen";
|
||||
import type { Spec } from "@json-render/core";
|
||||
|
||||
export function generateNextJSProject(spec: Spec): GeneratedFile[] {
|
||||
const files: GeneratedFile[] = [];
|
||||
const components = collectUsedComponents(spec);
|
||||
// Generate package.json, component files, main page...
|
||||
return files;
|
||||
}
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: json-render-core
|
||||
name: core
|
||||
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.
|
||||
---
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: json-render-image
|
||||
name: image
|
||||
description: Image renderer for json-render that turns JSON specs into SVG and PNG images via Satori. Use when working with @json-render/image, generating OG images from JSON, creating social cards, or rendering AI-generated image specs.
|
||||
---
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
name: jotai
|
||||
description: Jotai adapter for json-render's StateStore interface. Use when integrating json-render with Jotai for state management via @json-render/jotai.
|
||||
---
|
||||
|
||||
# @json-render/jotai
|
||||
|
||||
Jotai adapter for json-render's `StateStore` interface. Wire a Jotai atom as the state backend for json-render.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @json-render/jotai @json-render/core @json-render/react jotai
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { atom } from "jotai";
|
||||
import { jotaiStateStore } from "@json-render/jotai";
|
||||
import { StateProvider } from "@json-render/react";
|
||||
|
||||
// 1. Create an atom that holds the json-render state
|
||||
const uiAtom = atom<Record<string, unknown>>({ count: 0 });
|
||||
|
||||
// 2. Create the json-render StateStore adapter
|
||||
const store = jotaiStateStore({ atom: uiAtom });
|
||||
|
||||
// 3. Use it
|
||||
<StateProvider store={store}>
|
||||
{/* json-render reads/writes go through Jotai */}
|
||||
</StateProvider>
|
||||
```
|
||||
|
||||
### With a Shared Jotai Store
|
||||
|
||||
When your app already uses a Jotai `<Provider>` with a custom store, pass it so both json-render and your components share the same state:
|
||||
|
||||
```tsx
|
||||
import { atom, createStore } from "jotai";
|
||||
import { Provider as JotaiProvider } from "jotai/react";
|
||||
import { jotaiStateStore } from "@json-render/jotai";
|
||||
import { StateProvider } from "@json-render/react";
|
||||
|
||||
const jStore = createStore();
|
||||
const uiAtom = atom<Record<string, unknown>>({ count: 0 });
|
||||
|
||||
const store = jotaiStateStore({ atom: uiAtom, store: jStore });
|
||||
|
||||
<JotaiProvider store={jStore}>
|
||||
<StateProvider store={store}>
|
||||
{/* Both json-render and useAtom() see the same state */}
|
||||
</StateProvider>
|
||||
</JotaiProvider>
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `jotaiStateStore(options)`
|
||||
|
||||
Creates a `StateStore` backed by a Jotai atom.
|
||||
|
||||
| Option | Type | Required | Description |
|
||||
|--------|------|----------|-------------|
|
||||
| `atom` | `WritableAtom<StateModel, [StateModel], void>` | Yes | A writable atom holding the state model |
|
||||
| `store` | Jotai `Store` | No | The Jotai store instance. Defaults to a new store. Pass your own to share state with `<Provider>`. |
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user