emulate
Local drop-in replacement services for CI and no-network sandboxes. Fully stateful, production-fidelity API emulation. Not mocks.
The Generative UI framework. Generate dynamic, personalized UIs from prompts without sacrificing reliability. Predefined components and actions for safe, predictable output.
$ npx -y skills add vercel-labs/json-render --agent claude-code
Run the curl in your terminal, the rest in Claude Code.
Repo: vercel-labs/json-render
What's inside
The Generative UI framework.
Generate dynamic, personalized UIs from prompts without sacrificing reliability. Predefined components and actions for safe, predictable output.
# for React
npm install @json-render/core @json-render/react
# for React with pre-built shadcn/ui components
npm install @json-render/shadcn
# or for React Native
npm install @json-render/core @json-render/react-native
# or for video
npm install @json-render/core @json-render/remotion
# or for PDF documents
npm install @json-render/core @json-render/react-pdf
# or for HTML email
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
# or for SolidJS
npm install @json-render/core @json-render/solid
# or for terminal UIs
npm install @json-render/core @json-render/ink ink react
# or for full Next.js apps (routes, layouts, SSR, metadata)
npm install @json-render/core @json-render/react @json-render/next
# or for 3D scenes (and gaussian splatting via the GaussianSplat component)
npm install @json-render/core @json-render/react-three-fiber @react-three/fiber @react-three/drei three
json-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:
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/react/schema";
import { z } from "zod";
const catalog = defineCatalog(schema, {
components: {
Card: {
props: z.object({ title: z.string() }),
description: "A card container",
},
Metric: {
props: z.object({
label: z.string(),
value: z.string(),
format: z.enum(["currency", "percent", "number"]).nullable(),
}),
description: "Display a metric value",
},
Button: {
props: z.object({
label: z.string(),
action: z.string(),
}),
description: "Clickable button",
},
},
actions: {
export_report: { description: "Export dashboard to PDF" },
refresh_data: { description: "Refresh all metrics" },
},
});
import { defineRegistry, Renderer } from "@json-render/react";
const { registry } = defineRegistry(catalog, {
components: {
Card: ({ props, children }) => (
<div className="card">
<h3>{props.title}</h3>
{children}
</div>
),
Metric: ({ props }) => (
<div className="metric">
<span>{props.label}</span>
<span>{format(props.value, props.format)}</span>
</div>
),
Button: ({ props, emit }) => (
<button onClick={() => emit("press")}>{props.label}</button>
),
},
});
function Dashboard({ spec }) {
return <Renderer spec={spec} registry={registry} />;
}
That's it. AI generates JSON, you render it safely.
| Package | Description |
|---|---|
@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/solid | SolidJS renderer with fine-grained reactive contexts |
@json-render/shadcn | 36 pre-built shadcn/ui components (Radix UI + Tailwind CSS) |
@json-render/shadcn-svelte | 36 pre-built shadcn-svelte components (Svelte 5 + Tailwind CSS) |
@json-render/react-three-fiber | React Three Fiber renderer for 3D scenes (20 built-in components, including GaussianSplat) |
@json-render/react-native | React Native renderer with standard mobile components |
@json-render/next | Next.js renderer โ JSON becomes full apps with routes, layouts, SSR |
@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/ink | Ink terminal renderer with built-in components for interactive TUIs. |
@json-render/image | Image renderer for SVG/PNG output (OG images, social cards) via Satori |
@json-render/directives | Pre-built custom directives โ $format, $math, $concat, $count, $truncate, $pluralize, $join, $t (i18n) |
@json-render/codegen | Utilities for generating code from json-render UI trees |
@json-render/devtools | Framework-agnostic devtools core โ panel UI, event store, picker, stream taps |
@json-render/devtools-react | React adapter for @json-render/devtools (drop-in <JsonRenderDevtools />) |
@json-render/devtools-vue | Vue adapter for @json-render/devtools |
@json-render/devtools-svelte | Svelte adapter for @json-render/devtools |
@json-render/devtools-solid | SolidJS adapter for @json-render/devtools |
@json-render/redux | Redux / Redux Toolkit adapter for StateStore |
@json-render/zustand | Zustand adapter for StateStore |
@json-render/jotai | Jotai adapter for StateStore |
@json-render/xstate | XState Store (atom) adapter for StateStore |
@json-render/mcp | MCP Apps integration for Claude, ChatGPT, Cursor, VS Code |
@json-render/yaml | YAML wire format with streaming parser, edit modes, AI SDK transform |
import { defineRegistry, Renderer } from "@json-render/react";
import { schema } from "@json-render/react/schema";
// Flat spec format (root key + elements map)
const spec = {
root: "card-1",
elements: {
"card-1": {
type: "Card",
props: { title: "Hello" },
children: ["button-1"],
},
"button-1": {
type: "Button",
props: { label: "Click me" },
children: [],
},
},
};
// defineRegistry creates a type-safe component registry
const { registry } = defineRegistry(catalog, { components });
<Renderer spec={spec} registry={registry} />;
import { h } from "vue";
import { defineRegistry, Renderer } from "@json-render/vue";
import { schema } from "@json-render/vue/schema";
const { registry } = defineRegistry(catalog, {
components: {
Card: ({ props, children }) =>
h("div", { class: "card" }, [h("h3", null, props.title), children]),
Button: ({ props, emit }) =>
h("button", { onClick: () => emit("press") }, props.label),
},
});
// In your Vue component template:
// <Renderer :spec="spec" :registry="registry" />
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} />
import { defineRegistry, Renderer } from "@json-render/solid";
import { schema } from "@json-render/solid/schema";
const { registry } = defineRegistry(catalog, {
components: {
Card: (renderProps) => <div>{renderProps.children}</div>,
Button: (renderProps) => (
<button onClick={() => renderProps.emit("press")}>
{renderProps.element.props.label as string}
</button>
),
},
});
<Renderer spec={spec} registry={registry} />;
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/react/schema";
import { defineRegistry, Renderer } from "@json-render/react";
import { shadcnComponentDefinitions } from "@json-render/shadcn/catalog";
import { shadcnComponents } from "@json-render/shadcn";
// Pick components from the 36 standard definitions
const catalog = defineCatalog(schema, {
components: {
Card: shadcnComponentDefinitions.Card,
Stack: shadcnComponentDefinitions.Stack,
Heading: shadcnComponentDefinitions.Heading,
Button: shadcnComponentDefinitions.Button,
},
actions: {},
});
// Use matching implementations
const { registry } = defineRegistry(catalog, {
components: {
Card: shadcnComponents.Card,
Stack: shadcnComponents.Stack,
Heading: shadcnComponents.Heading,
Button: shadcnComponents.Button,
},
});
<Renderer spec={spec} registry={registry} />;
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/react-native/schema";
import {
standardComponentDefinitions,
standardActionDefinitions,
} from "@json-render/react-native/catalog";
import { defineRegistry, Renderer } from "@json-render/react-native";
// 25+ standard components included
const catalog = defineCatalog(schema, {
components: { ...standardComponentDefinitions },
actions: standardActionDefinitions,
});
const { registry } = defineRegistry(catalog, { components: {} });
<Renderer spec={spec} registry={registry} />;
import { Player } from "@remotion/player";
import {
Renderer,
schema,
standardComponentDefinitions,
} from "@json-render/remotion";
// Timeline spec format
const spec = {
composition: {
id: "video",
fps: 30,
width: 1920,
height: 1080,
durationInFrames: 300,
},
tracks: [{ id: "main", name: "Main", type: "video", enabled: true }],
clips: [
{
id: "clip-1",
trackId: "main",
component: "TitleCard",
props: { title: "Hello" },
from: 0,
durationInFrames: 90,
},
],
audio: { tracks: [] },
};
<Player
component={Renderer}
inputProps={{ spec }}
durationInFrames={spec.composition.durationInFrames}
fps={spec.composition.fps}
compositionWidth={spec.composition.width}
compositionHeight={spec.composition.height}
/>;
import { renderToBuffer } from "@json-render/react-pdf";
const spec = {
root: "doc",
elements: {
doc: {
type: "Document",
props: { title: "Invoice" },
children: ["page-1"],
},
"page-1": {
type: "Page",
props: { size: "A4" },
children: ["heading-1", "table-1"],
},
"heading-1": {
type: "Heading",
props: { text: "Invoice #1234", level: "h1" },
children: [],
},
"table-1": {
type: "Table",
props: {
columns: [
{ header: "Item", width: "60%" },
{ header: "Price", width: "40%", align: "right" },
],
rows: [
["Widget A", "$10.00"],
["Widget B", "$25.00"],
],
},
children: [],
},
},
};
// Render to buffer, stream, or file
const buffer = await renderToBuffer(spec);
import { renderToHtml } from "@json-render/react-email";
import { schema, standardComponentDefinitions } from "@json-render/react-email";
import { defineCatalog } from "@json-render/core";
const catalog = defineCatalog(schema, {
components: standardComponentDefinitions,
});
const spec = {
root: "html-1",
elements: {
"html-1": {
type: "Html",
props: { lang: "en", dir: "ltr" },
children: ["head-1", "body-1"],
},
"head-1": { type: "Head", props: {}, children: [] },
"body-1": {
type: "Body",
props: { style: { backgroundColor: "#f6f9fc" } },
children: ["container-1"],
},
"container-1": {
type: "Container",
props: {
style: { maxWidth: "600px", margin: "0 auto", padding: "20px" },
},
children: ["heading-1", "text-1"],
},
"heading-1": { type: "Heading", props: { text: "Welcome" }, children: [] },
"text-1": {
type: "Text",
props: { text: "Thanks for signing up." },
children: [],
},
},
};
const html = await renderToHtml(spec);
import { renderToPng } from "@json-render/image/render";
const spec = {
root: "frame",
elements: {
frame: {
type: "Frame",
props: { width: 1200, height: 630, backgroundColor: "#1a1a2e" },
children: ["heading"],
},
heading: {
type: "Heading",
props: { text: "Hello World", level: "h1", color: "#ffffff" },
children: [],
},
},
};
// Render to PNG (requires @resvg/resvg-js)
const png = await renderToPng(spec, { fonts });
// Or render to SVG string
import { renderToSvg } from "@json-render/image/render";
const svg = await renderToSvg(spec, { fonts });
import { defineCatalog } from "@json-render/core";
import { schema, defineRegistry } from "@json-render/react";
import {
threeComponentDefinitions,
threeComponents,
ThreeCanvas,
} from "@json-render/react-three-fiber";
const catalog = defineCatalog(schema, {
components: {
Box: threeComponentDefinitions.Box,
Sphere: threeComponentDefinitions.Sphere,
AmbientLight: threeComponentDefinitions.AmbientLight,
DirectionalLight: threeComponentDefinitions.DirectionalLight,
GaussianSplat: threeComponentDefinitions.GaussianSplat,
OrbitControls: threeComponentDefinitions.OrbitControls,
},
actions: {},
});
const { registry } = defineRegistry(catalog, {
components: {
Box: threeComponents.Box,
Sphere: threeComponents.Sphere,
AmbientLight: threeComponents.AmbientLight,
DirectionalLight: threeComponents.DirectionalLight,
GaussianSplat: threeComponents.GaussianSplat,
OrbitControls: threeComponents.OrbitControls,
},
});
<ThreeCanvas
spec={spec}
registry={registry}
shadows
camera={{ position: [5, 5, 5], fov: 50 }}
style={{ width: "100%", height: "100vh" }}
/>;
import type { NextAppSpec } from "@json-render/next";
import { createNextApp } from "@json-render/next/server";
import { NextAppProvider } from "@json-render/next";
const spec: NextAppSpec = {
metadata: { title: { default: "My App", template: "%s | My App" } },
layouts: {
main: {
root: "shell",
elements: {
shell: { type: "Container", props: {}, children: ["nav", "slot"] },
nav: { type: "NavBar", props: {}, children: [] },
slot: { type: "Slot", props: {}, children: [] },
},
},
},
routes: {
"/": {
layout: "main",
metadata: { title: "Home" },
page: {
root: "hero",
elements: {
hero: { type: "Card", props: { title: "Welcome" }, children: [] },
},
},
},
},
};
// Server: creates Page, generateMetadata, generateStaticParams
const app = createNextApp({ spec });
// Client: wrap your layout with NextAppProvider
// <NextAppProvider registry={registry} handlers={handlers}>
// {children}
// </NextAppProvider>
import { defineCatalog } from "@json-render/core";
import { schema } from "@json-render/svelte/schema";
import { defineRegistry, Renderer } from "@json-render/svelte";
import { shadcnComponentDefinitions } from "@json-render/shadcn-svelte/catalog";
import { shadcnComponents } from "@json-render/shadcn-svelte";
const catalog = defineCatalog(schema, {
components: {
Card: shadcnComponentDefinitions.Card,
Stack: shadcnComponentDefinitions.Stack,
Heading: shadcnComponentDefinitions.Heading,
Button: shadcnComponentDefinitions.Button,
},
actions: {},
});
const { registry } = defineRegistry(catalog, {
components: {
Card: shadcnComponents.Card,
Stack: shadcnComponents.Stack,
Heading: shadcnComponents.Heading,
Button: shadcnComponents.Button,
},
});
// In your Svelte component:
// <Renderer spec={spec} registry={registry} />
Drop-in inspector panel for any json-render app. Spec tree, state editor, action log, stream log, catalog browser, DOM picker.
// React
import { JsonRenderDevtools } from "@json-render/devtools-react";
<JSONUIProvider registry={registry} handlers={handlers}>
<Renderer spec={spec} registry={registry} />
<JsonRenderDevtools spec={spec} catalog={catalog} messages={messages} />
</JSONUIProvider>;
Floating toggle appears bottom-right. Hotkey: Ctrl/Cmd + Shift + J. Tree-shakes to null in production.
Available for React, Vue, Svelte, and Solid โ swap @json-render/devtools-react for the adapter that matches your renderer.
import { defineCatalog } from "@json-render/core";
import {
schema,
standardComponentDefinitions,
standardActionDefinitions,
defineRegistry,
Renderer,
JSONUIProvider,
} from "@json-render/ink";
const catalog = defineCatalog(schema, {
components: { ...standardComponentDefinitions },
actions: standardActionDefinitions,
});
const { registry } = defineRegistry(catalog, { components: {} });
const spec = {
root: "card-1",
elements: {
"card-1": {
type: "Card",
props: { title: "Status" },
children: ["status-1"],
},
"status-1": {
type: "StatusLine",
props: { label: "Build", status: "success" },
children: [],
},
},
};
<JSONUIProvider initialState={{}}>
<Renderer spec={spec} registry={registry} />
</JSONUIProvider>;
Stream AI responses progressively:
import { createSpecStreamCompiler } from "@json-render/core";
const compiler = createSpecStreamCompiler<MySpec>();
// Process chunks as they arrive
const { result, newPatches } = compiler.push(chunk);
setSpec(result); // Update UI with partial result
// Get final result
const finalSpec = compiler.getResult();
Generate system prompts from your catalog:
const systemPrompt = catalog.prompt();
// Includes component descriptions, props schemas, available actions
{
"type": "Alert",
"props": { "message": "Error occurred" },
"visible": [
{ "$state": "/form/hasError" },
{ "$state": "/form/errorDismissed", "not": true }
]
}
Any prop value can be data-driven using expressions:
{
"type": "Icon",
"props": {
"name": {
"$cond": { "$state": "/activeTab", "eq": "home" },
"$then": "home",
"$else": "home-outline"
},
"color": {
"$cond": { "$state": "/activeTab", "eq": "home" },
"$then": "#007AFF",
"$else": "#8E8E93"
}
}
}
Expression forms:
{ "$state": "/state/key" } - reads a value from the state model{ "$cond": <condition>, "$then": <value>, "$else": <value> } - evaluates a condition and picks a branch{ "$template": "Hello, ${/user/name}!" } - interpolates state values into strings{ "$computed": "fn", "args": { ... } } - calls a registered function with resolved argsComponents can trigger actions, including the built-in setState action:
{
"type": "Pressable",
"props": {
"action": "setState",
"actionParams": { "statePath": "/activeTab", "value": "home" }
},
"children": ["home-icon"]
}
The setState action updates the state model directly, which re-evaluates visibility conditions and dynamic prop expressions.
React to state changes by triggering actions:
{
"type": "Select",
"props": {
"value": { "$bindState": "/form/country" },
"options": ["US", "Canada", "UK"]
},
"watch": {
"/form/country": {
"action": "loadCities",
"params": { "country": { "$state": "/form/country" } }
}
}
}
watch is a top-level field on elements (sibling of type/props/children). Watchers fire when the watched value changes, not on initial render.
git clone https://github.com/vercel-labs/json-render
cd json-render
pnpm install
pnpm dev
pnpm dev in examples/chatpnpm dev in examples/svelte or examples/svelte-chatpnpm dev in examples/vuepnpm dev in examples/vite-renderersnpx expo start in examples/react-nativepnpm dev in examples/react-three-fiber-gsplatpnpm dev in examples/gsplatflowchart LR
A[User Prompt] --> B[AI + Catalog]
B --> C[JSON Spec]
C --> D[Renderer]
B -.- E([guardrailed])
C -.- F([predictable])
D -.- G([streamed])
Apache-2.0
.cursor/
mcp.json
.github/
workflows/
ci.yml
release.yml
.gitignore
.husky/
pre-commit
.node-version
.npmrc
.vscode/
mcp.json
AGENTS.md
apps/
web/
.env.example
.gitignore
app/
(main)/
docs/
a2ui/
page.mdx
adaptive-cards/
page.mdx
ag-ui/
page.mdx
ai-sdk/
page.mdx
api/
codegen/
page.mdx
core/
page.mdx
devtools/
devtools-react/
page.mdx
devtools-solid/
page.mdx
devtools-svelte/
page.mdx
devtools-vue/
page.mdx
page.mdx
directives/
page.mdx
image/
page.mdx
ink/
page.mdx
jotai/
page.mdx
mcp/
page.mdx
next/
page.mdx
react/
react-email/
page.mdx
react-native/
page.mdx
react-pdf/
page.mdx
react-three-fiber/
page.mdx
page.mdx
redux/
page.mdx
remotion/
page.mdx
shadcn/
shadcn-svelte/
page.mdx
page.mdx
solid/
page.mdx
svelte/
page.mdx
vue/
page.mdx
xstate/
page.mdx
yaml/
page.mdx
zustand/
page.mdx
catalog/
page.mdx
changelog/
page.mdx
code-export/
page.mdx
computed-values/
page.mdx
custom-schema/
page.mdx
data-binding/
page.mdx
devtools/
page.mdx
directives/
page.mdx
generation-modes/
page.mdx
installation/
page.mdx
layout.tsx
migration/
page.mdx
openapi/
page.mdx
page.mdx
quick-start/
page.mdx
registry/
page.mdx
renderers/
page.mdx
schemas/
page.mdx
skills/
page.mdx
specs/
page.mdx
streaming/
page.mdx
validation/
page.mdx
visibility/
page.mdx
watchers/
page.mdx
examples/
page.tsx
layout.tsx
page.tsx
api/
docs-chat/
route.ts
docs-markdown/
route.ts
generate/
route.ts
search/
route.ts
favicon.ico
fonts/
GeistMonoVF.woff
GeistVF.woff
globals.css
layout.tsx
not-found.tsx
og/
[...slug]/
route.tsx
og-image.tsx
route.tsx
playground/
layout.tsx
page.tsx
CHANGELOG.md
components/
components.json
code-block.tsx
code-tabs.tsx
code.tsx
copy-button.tsx
copy-page-button.tsx
demo.tsx
docs-chat.tsx
docs-mobile-nav.tsx
docs-sidebar.tsx
expandable-code.tsx
generation-modes-diagram.tsx
header.tsx
package-install.tsx
playground.tsx
search.tsx
table-of-contents.tsx
theme-provider.tsx
theme-toggle.tsx
ui/
accordion.tsx
alert.tsx
badge.tsx
button.tsx
card.tsx
carousel.tsx
checkbox.tsx
collapsible.tsx
dialog.tsx
drawer.tsx
dropdown-menu.tsx
input.tsx
label.tsx
pagination.tsx
popover.tsx
progress.tsx
radio-group.tsx
resizable.tsx
select.tsx
separator.tsx
sheet.tsx
skeleton.tsx
slider.tsx
sonner.tsx
switch.tsx
table.tsx
tabs.tsx
textarea.tsx
toggle-group.tsx
toggle.tsx
tooltip.tsx
eslint.config.js
lib/
docs-navigation.ts
examples.ts
github.ts
mdx-to-markdown.ts
page-metadata.ts
page-titles.ts
rate-limit.ts
render/
catalog-display.ts
catalog.ts
registry.tsx
renderer.tsx
search-index.ts
spec-patch.ts
use-playground-stream.ts
utils.ts
mdx-components.tsx
next.config.js
package.json
postcss.config.mjs
public/
Geist-Regular.ttf
GeistPixel-Square.ttf
README.md
tsconfig.json
CHANGELOG.md
examples/
chat/
.env.example
app/
api/
generate/
route.ts
globals.css
layout.tsx
opengraph-image.png
page.tsx
CHANGELOG.md
components/
theme-provider.tsx
theme-toggle.tsx
ui/
accordion.tsx
alert.tsx
badge.tsx
button.tsx
card.tsx
chart.tsx
input.tsx
label.tsx
progress.tsx
radio-group.tsx
select.tsx
separator.tsx
skeleton.tsx
table.tsx
tabs.tsx
eslint.config.js
lib/
agent.ts
rate-limit.ts
render/
catalog.ts
registry.tsx
renderer.tsx
tools/
crypto.ts
github.ts
hackernews.ts
search.ts
weather.ts
utils.ts
next.config.ts
package.json
postcss.config.mjs
README.md
tsconfig.json
dashboard/
.env.example
app/
api/
generate/
route.ts
v1/
accounts/
[id]/
route.ts
route.ts
customers/
[id]/
route.ts
route.ts
expenses/
[id]/
approve/
route.ts
reject/
route.ts
route.ts
route.ts
invoices/
[id]/
mark-paid/
route.ts
route.ts
send/
route.ts
route.ts
reports/
export/
route.ts
profit-loss/
route.ts
reset/
route.ts
widgets/
[id]/
route.ts
reorder/
route.ts
route.ts
fonts/
GeistMonoVF.woff
GeistVF.woff
globals.css
layout.tsx
opengraph-image.png
page.tsx
CHANGELOG.md
components/
components.json
add-widget-card.tsx
code-highlight.tsx
header.tsx
sortable-widget.tsx
theme-provider.tsx
theme-toggle.tsx
ui/
accordion.tsx
alert.tsx
animated-border.tsx
avatar.tsx
badge.tsx
button.tsx
card.tsx
chart.tsx
checkbox.tsx
dialog.tsx
drawer.tsx
dropdown-menu.tsx
input.tsx
label.tsx
pagination.tsx
popover.tsx
progress.tsx
radio-group.tsx
select.tsx
separator.tsx
skeleton.tsx
switch.tsx
table.tsx
tabs.tsx
textarea.tsx
tooltip.tsx
widget.tsx
drizzle.config.ts
eslint.config.js
lib/
db/
connection.ts
schema.ts
store.ts
rate-limit.ts
render/
catalog.ts
registry.tsx
renderer.tsx
utils.ts
next.config.js
package.json
postcss.config.mjs
README.md
scripts/
clear.ts
seed.ts
... 1600 moreShowing a partial view of a very large repo.
Local drop-in replacement services for CI and no-network sandboxes. Fully stateful, production-fidelity API emulation. Not mocks.
Browser automation CLI for AI agents. Fast native Rust CLI.
Give coding agents access to any package's source code.
FAQ
json-render is a Claude Code plugin with 26 hand-picked skills for development work, indexed on Flowy. Install it with the command on its page. It includes codegen, core, devtools. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.