OpenSource-Hub

json-render

フレームワーク

vercel-labs/json-render

ジェネレーティブ UI フレームワーク。AI が生成した JSON を安全にインターフェースとしてレンダリングします。

概要

json-render は生成型 UI フレームワークで、AI が自然言語プロンプトに基づいてインターフェースを生成でき、事前に定義したコンポーネントのみを使用します。出力される JSON は常にスキーマに準拠しており、安全で信頼性が高く、ストリーミングレンダリングをサポートしています。React、Vue、Svelte、React Native、3D、ビデオ、PDF、メール、ターミナルなど、多様なプラットフォーム向けのレンダラーを提供しています。

README プレビュー

# json-render\n\n**The Generative UI framework.**\n\nGenerate dynamic, personalized UIs from prompts without sacrificing reliability. Predefined components and actions for safe, predictable output.\n\n\n  \n  \n  \n  \n\n\n```bash\n# for React\nnpm install @json-render/core @json-render/react\n# for React with pre-built shadcn/ui components\nnpm install @json-render/shadcn\n# or for React Native\nnpm install @json-render/core @json-render/react-native\n# or for video\nnpm install @json-render/core @json-render/remotion\n# or for PDF documents\nnpm install @json-render/core @json-render/react-pdf\n# or for HTML email\nnpm install @json-render/core @json-render/react-email @react-email/components @react-email/render\n# or for Vue\nnpm install @json-render/core @json-render/vue\n# or for Svelte\nnpm install @json-render/core @json-render/svelte\n# or for SolidJS\nnpm install @json-render/core @json-render/solid\n# or for terminal UIs\nnpm install @json-render/core @json-render/ink ink react\n# or for full Next.js apps (routes, layouts, SSR, metadata)\nnpm install @json-render/core @json-render/react @json-render/next\n# or for 3D scenes (and gaussian splatting via the GaussianSplat component)\nnpm install @json-render/core @json-render/react-three-fiber @react-three/fiber @react-three/drei three\n```\n\n## Why json-render?\n\njson-render is a **Generative UI** framework: AI generates interfaces from natural language prompts, constrained to components you define. You set the guardrails, AI generates within them:\n\n- **Guardrailed** - AI can only use components in your catalog\n- **Predictable** - JSON output matches your schema, every time\n- **Fast** - Stream and render progressively as the model responds\n- **Cross-Platform** - React, Vue, Svelte, Solid (web), React Native (mobile) from the same catalog\n- **Batteries Included** - 36 pre-built shadcn/ui components ready to use\n\n## Quick Start\n\n### 1. Define Your Catalog\n\n```typescript\nimport { defineCatalog } 

FAQ (5)

トラブル対応
Zod 4.4 にアップグレードした後、@json-render で visible フィールドに表示される "Invalid input: expected nonoptional, received undefined" エラーを修正する方法

これは @json-render(≤0.19.0)における Zod 4.4 との互換性バグで、要素のオプションの visible フィールドが catalog.validate() の実行時に誤って必須として扱われます。修正方法:すべての @json-render パッケージ(core、react、shadcn、react-email)を v0.20.0 以降にアップグレードしてください。修正は PR #299 で取り込まれ、zod 4.6 と組み合わせた v0.21.1 で動作が確認されています。すぐにアップグレードできない場合は、一時的な回避策として zod を 4.3.6 に固定してください(pnpm add zod@4.3.6)。zod 4.4.x のどのバージョンでもこの障害が発生するためです。

参照 Issue #287
トラブル対応
@json-render/solid で useBoundProp を使用する際に発生する「value is not a function」エラーの修正方法

README の例は間違っていました。useBoundProp(propsValue, binding) はタプル [T | undefined, (value: T) => void] を返し、最初の要素は Solid のアクセサーではなく生の prop の値です。value() として呼び出さないでください。正しい使用方法:

Input: (ctx) => {
  const [value, setValue] = useBoundProp(ctx.props.value, ctx.bindings?.value);
  return (
    <input
      value={String(value ?? "")}
      onInput={(event) => setValue(event.currentTarget.value)}
    />
  );
}

解決された値は JSX 内で直接読み取り、Solid がリアクティブな読み取りを追跡できるようにしてください。更新にはセッター(setValue)を使用します。ドキュメントの例は PR #401(#381 と併せて)で修正され、初期値、外部状態の更新、null 値をカバーしています。

参照 Issue #382
トラブル対応
なぜ @json-render/solid の defineRegistry コールバックで 'Cannot read properties of undefined (reading props)' が発生するのですか?

defineRegistry() のコールバックコンテキストには element フィールドは含まれていません。古い README の例では誤って renderProps.element.props を使用していました。このコールバックは、解決済みの props を ctx.props 経由で(children、emit、on、bindings、loading とともに)直接受け取ります。コンポーネントのコールバックを修正し、コンテキストのルートから props を読み取るようにしてください:

const { registry } = defineRegistry(catalog, {
  components: {
    Card: (ctx) => (
      <div class="card">
        <h3>{ctx.props.title as string}</h3>
        {ctx.children}
      </div>
    ),
  },
});

注意: element を公開しているのは低レベルの ComponentRenderer コントラクトのみであり、defineRegistry() アダプターは公開していません。README の例は PR #401 で修正され、解決済みのコンテキストを使用し、入力値をリアクティブに保ち、レンダラーに必要なプロバイダーを含めるようになりました。

参照 Issue #381
トラブル対応
json-renderで「setValue does not exist on useFieldValidation」エラーを修正する方法

useFieldValidation はバリデーションのみを処理します(errors と validate を返します)。value や setValue は提供しません。これらは代わりに useBoundProp フックから取得してください。正しい使用方法:

import { useBoundProp, useFieldValidation } from '@json-render/react';

function TextField({ element }) {
  const [value, setValue] = useBoundProp(element.props.valuePath);
  const { errors, validate } = useFieldValidation(
    element.props.valuePath,
    element.props.checks
  );

  return (
    <div>
      <label>{element.props.label}</label>
      <input
        value={value || ''}
        onChange={(e) => setValue(e.target.value)}
        onBlur={() => validate()}
      />
      {errors.map((error, i) => (
        <p key={i} className="text-red-500 text-sm">{error}</p>
      ))}
    </div>
  );
}

これはドキュメントの誤りで、issue #107 で修正されました。useBoundProp の setValue を使わずにデータを直接設定するとバインディング層がバイパスされるため、バリデーションが正しくトリガーされなかったのです。

参照 Issue #47
トラブル対応
なぜ json-render アクションのパラメータで $item は実際の値ではなく "list/0/url" のようなパス文字列を返すのですか?

json-render 0.19.0 (React) では、繰り返し要素(/list で repeat)内の action.params で { "$item": "url" } を使用すると、フィールドの実際の値ではなく、JSON パス文字列(例: "list/0/url")に誤って解決されます。**回避策:** action params 内の $item を $bindItem に置き換えます: "params": { "url": { "$bindItem": "url" } } — これにより、実際のフィールド値が正しく返されます。

参照 Issue #292