
Solid
Wire @json-render/solid catalogs, registries, and Renderer providers when generating UI from JSON specs in SolidJS.
Overview
@json-render/solid is an agent skill for the Build phase that shows how to render json-render specs as Solid component trees with catalogs, registries, providers, and Solid-specific reactivity.
Install
npx skills add https://github.com/vercel-labs/json-render --skill solidWhat is this skill?
- Quick-start pattern with JSONUIProvider, Renderer, and a typed Spec prop
- defineCatalog from @json-render/core with @json-render/solid/schema and Zod component props
- ComponentRenderProps contract for custom Solid components in the registry
- Actions and bindings for interactive json-render specs in Solid
- Troubleshooting guidance for fine-grained Solid reactivity with dynamic specs
- defineCatalog pattern with Zod props for Button and Card examples
- ComponentRenderProps interface for registry components
Adoption & trust: 565 installs on skills.sh; 15k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You have JSON UI specs and the core json-render model but no reliable SolidJS patterns for catalogs, Renderer wiring, or reactive updates.
Who is it for?
Builders adding json-render-driven or agent-generated UI to a SolidJS codebase with @json-render/core already in play.
Skip if: Teams on React-only json-render without Solid, or greenfield UI with no JSON spec pipeline.
When should I use this skill?
Building @json-render/solid catalogs/registries, wiring Renderer providers, implementing bindings/actions, or troubleshooting Solid-specific reactivity patterns.
What do I get? / Deliverables
You get working Solid provider/registry setup, Zod catalogs, and binding patterns so specs render and update correctly in Solid apps.
- Solid catalog and registry modules
- JSONUIProvider-wrapped Renderer integration
- Working bindings/actions for interactive spec nodes
Recommended Skills
Journey fit
How it compares
Framework adapter documentation for json-render—not a general Solid tutorial or a full design-system generator.
Common Questions / FAQ
Who is solid for?
Solo builders and small teams using SolidJS with Vercel json-render who need agent-accurate setup for catalogs, registries, and Renderer providers.
When should I use solid?
During Build (frontend) when defining @json-render/solid catalogs, wiring JSONUIProvider and Renderer, implementing bindings/actions, or fixing Solid reactivity with dynamic specs.
Is solid safe to install?
It is documentation-only procedural knowledge; review the Security Audits panel on this Prism page and your org policy before pulling from the skills registry.
SKILL.md
READMESKILL.md - Solid
# @json-render/solid `@json-render/solid` renders json-render specs into Solid component trees with fine-grained reactivity. ## Quick Start ```tsx import { Renderer, JSONUIProvider } from "@json-render/solid"; import type { Spec } from "@json-render/solid"; import { registry } from "./registry"; export function App(props: { spec: Spec | null }) { return ( <JSONUIProvider registry={registry} initialState={{}}> <Renderer spec={props.spec} registry={registry} /> </JSONUIProvider> ); } ``` ## Create a Catalog ```typescript import { defineCatalog } from "@json-render/core"; import { schema } from "@json-render/solid/schema"; import { z } from "zod"; export const catalog = defineCatalog(schema, { components: { Button: { props: z.object({ label: z.string(), variant: z.enum(["primary", "secondary"]).nullable(), }), description: "Clickable button", }, Card: { props: z.object({ title: z.string() }), description: "Card container", }, }, actions: { submit: { description: "Submit data" }, }, }); ``` ## Define Components Components receive `ComponentRenderProps` from the renderer: ```ts interface ComponentRenderProps<P = Record<string, unknown>> { element: UIElement<string, P>; children?: JSX.Element; emit: (event: string) => void; on: (event: string) => EventHandle; bindings?: Record<string, string>; loading?: boolean; } ``` Example: ```tsx import type { BaseComponentProps } from "@json-render/solid"; export function Button(props: BaseComponentProps<{ label: string }>) { return ( <button onClick={() => props.emit("press")}>{props.props.label}</button> ); } ``` ## Create a Registry ```typescript import { defineRegistry } from "@json-render/solid"; import { catalog } from "./catalog"; import { Card } from "./Card"; import { Button } from "./Button"; const { registry, handlers, executeAction } = defineRegistry(catalog, { components: { Card, Button, }, actions: { submit: async (params, setState, state) => { // custom action logic }, }, }); ``` ## Spec Structure ```json { "root": "card1", "elements": { "card1": { "type": "Card", "props": { "title": "Hello" }, "children": ["btn1"] }, "btn1": { "type": "Button", "props": { "label": "Click me" }, "on": { "press": { "action": "submit" } } } } } ``` ## Providers - `StateProvider`: state model read/write and controlled mode via `store` - `VisibilityProvider`: evaluates `visible` conditions - `ValidationProvider`: field validation + `validateForm` integration - `ActionProvider`: runs built-in and custom actions - `JSONUIProvider`: combined provider wrapper ## Hooks - `useStateStore`, `useStateValue`, `useStateBinding` - `useVisibility`, `useIsVisible` - `useActions`, `useAction` - `useValidation`, `useOptionalValidation`, `useFieldValidation` - `useBoundProp` - `useUIStream`, `useChatUI` ## Built-in Actions Handled automatically by `ActionProvider`: - `setState` - `pushState` - `removeState` - `validateForm` ## Dynamic Props and Bindings Supported expression forms include: - `{"$state": "/path"}` - `{"$bindState": "/path"}` - `{"$bindItem": "field"}` - `{"$template": "Hi ${/user/name}"}` - `{"$computed": "fn", "args": {...}}` - `{"$cond": <condition>, "$then": <value>, "$else": <value>}` Use `useBoundProp` in components for writable bound values: ```tsx import { useBoundProp } from "@json-render/solid"; function Input(props: BaseComponentProps<{ value?: string }>) { const [value, setValue] = useBoundProp( props.props.value, props.bindings?.value, ); return ( <input value={String(value() ?? "")} on