ork-assess
Assess a code change, design, architecture, workflow, or competing options against explicit criteria and evidence. Use when a…
One json-render spec to many targets: React, Next.js, React Native, Ink, PDF, email, Remotion, OG images, 3D. Use when one component spec must render on several platforms.
Claude Code
$ npx -y skills add yonatangross/orchestkit --skill multi-surface-render --agent claude-code
Codex
$ npx skills add yonatangross/orchestkit --skill multi-surface-render -a codex -y
Cursor
$ npx skills add yonatangross/orchestkit --skill multi-surface-render -a cursor -y
Gemini CLI
$ npx skills add yonatangross/orchestkit --skill multi-surface-render -a gemini-cli -y
GitHub Copilot
$ npx skills add yonatangross/orchestkit --skill multi-surface-render -a github-copilot -y
OpenCode
$ npx skills add yonatangross/orchestkit --skill multi-surface-render -a opencode -y
Windsurf
$ npx skills add yonatangross/orchestkit --skill multi-surface-render -a windsurf -y
name: multi-surface-render compatibility: "Claude Code 2.1.277+" description: "One json-render spec to many targets: React, Next.js, React Native, Ink, PDF, email, Remotion, OG images, 3D. Use when one component spec must render on several platforms." user-invocable: false disable-model-invocation: false context: inherit metadata: category: frontend upstream-package: "@json-render/core" upstream-version-tested: "0.21.3" version: "1.1.0" author: "OrchestKit" complexity: "medium" tags: "json-render, multi-surface, pdf, email, remotion, video, image, react, rendering, ink, nextjs"
Upstream version reference: `@json-render/core` 0.21.3 (2026-10-24).
Define once, render everywhere. A single json-render catalog and spec can produce React web UIs, PDF reports, HTML emails, Remotion demo videos, and OG images — each surface gets its own registry that maps catalog types to platform-native components.
| Category | Rules | Impact | When to Use | |----------|-------|--------|-------------| | [Target Selection](#target-selection) | 1 | HIGH | Choosing which renderer for your use case | | [React Renderer](#react-renderer) | 1 | MEDIUM | Web apps, SPAs, dashboards | | [PDF & Email Renderer](#pdf--email-renderer) | 1 | HIGH | Reports, documents, notifications | | [Video & Image Renderer](#video--image-renderer) | 1 | MEDIUM | Demo videos, OG images, social cards | | [Registry Mapping](#registry-mapping) | 1 | HIGH | Platform-specific component implementations |
**Total: 5 rules across 5 categories**
1. **One catalog** — Zod-typed component definitions shared across all surfaces 2. **One spec** — flat-tree JSON/YAML describing the UI structure 3. **Many registries** — each surface maps catalog types to its own component implementations 4. **Many renderers** — each package renders the spec using its registry
The catalog is the contract. The spec is the data. The registry is the platform-specific implementation.
import { defineCatalog } from '@json-render/core'
import { schema } from '@json-render/react/schema'
import { z } from 'zod'
export const catalog = defineCatalog(schema, {
components: {
Heading: {
props: z.object({
text: z.string(),
level: z.enum(['h1', 'h2', 'h3']),
}),
children: false,
},
Paragraph: {
props: z.object({ text: z.string() }),
children: false,
},
StatCard: {
props: z.object({
label: z.string(),
value: z.string(),
trend: z.enum(['up', 'down', 'flat']).optional(),
}),
children: false,
},
},
})import { Renderer } from '@json-render/react'
import { webRegistry } from './registries/web'
// webRegistry comes from `defineRegistry(catalog, { components })`.
// RendererProps is { spec, registry, loading?, fallback? } — no catalog prop.
export const Dashboard = ({ spec }) => (
<Renderer spec={spec} registry={webRegistry} />
)import { renderToBuffer, renderToFile } from '@json-render/react-pdf'
import { pdfRegistry } from './registries/pdf'
// Buffer for HTTP response. PDF options are { registry?, state?, handlers? }.
// includeStandard is an EMAIL option, not a PDF one (see references/upstream-pdf.md).
const buffer = await renderToBuffer(spec, { registry: pdfRegistry })
// Direct file output — renderToFile(spec, filePath, options?)
await renderToFile(spec, './output/report.pdf', { registry: pdfRegistry })import { renderToHtml } from '@json-render/react-email'
import { emailRegistry } from './registries/email'
const html = await renderToHtml(spec, { registry: emailRegistry })
await sendEmail({ to: user.email, subject: 'Weekly Report', html })import { renderToSvg, renderToPng } from '@json-render/image'
import { imageRegistry } from './registries/image'
const png = await renderToPng(spec, {
registry: imageRegistry,
width: 1200,
height: 630,
})// Verified 2026-10-26 against @json-render/remotion@0.21.3 (same exports as 0.19.0): the export is
// `Renderer` and its props are { spec, components }. fps and durationInFrames
// belong on Remotion's own Composition, not on this renderer.
import { Renderer } from '@json-render/remotion'
import { remotionComponents } from './registries/remotion'
export const DemoVideo = () => (
<Renderer spec={spec} components={remotionComponents} />
)import { render } from 'ink'
import { Renderer } from '@json-render/ink'
import { catalog } from './catalog'
import { inkRegistry } from './registries/ink'
render(<Renderer spec={spec} catalog={catalog} registry={inkRegistry} />)Useful for `/ork:*` CLI dashboards and streaming agent chat interfaces — ships 20+ Ink-native components (Box, Text, Spinner, Table, Markdown, Progress, etc.).
// createNextApp lives on the /server subpath, not the package root.
import { createNextApp } from '@json-render/next/server'
const { getPageData, generateMetadata, generateStaticParams } = createNextApp({
spec, // NextAppSpec: routes keyed by Next.js URL patterns
loaders: { getPost }, // server-side data loaders referenced by route.loader
})It does **not** scaffold a project on disk. `createNextApp` returns the server-side pieces you re-export from a catch-all route, and the page itself renders through `PageRenderer`:
// app/[[...slug]]/page.tsx
export { generateMetadata, generateStaticParams }
export default async function Page({ params }) {
const data = await getPageData(params)
if (!data) notFound()The Complete AI Development Toolkit for Claude Code. 115 skills, 36 agents, 163 hooks. Install `ork` for stable (v10.x).
Assess a code change, design, architecture, workflow, or competing options against explicit criteria and evidence. Use when a…
Compare plausible implementation, architecture, product, or operational approaches before committing to one. Use when a request…
Map an unfamiliar codebase, feature, architecture, data flow, or operational path with file-backed evidence. Use when a request…
Render an answer inline as compact ASCII or box-drawing art with semantic status icons. Use for status, inventories, budgets,…
Make an approved, scoped change and prove the affected behavior. Use when a request asks to implement, build, add, or land a…
Review a pull request or branch for correctness, regressions, security, operational risk, and missing evidence. Use when a…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.