Json-render react-pdf
React PDF renderer for json-render. Use when generating PDF documents from JSON specs, working with @json-render/react-pdf, or rendering specs to PDF buffers/streams/files.
install
source · Clone the upstream repo
git clone https://github.com/vercel-labs/json-render
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/vercel-labs/json-render "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/react-pdf" ~/.claude/skills/vercel-labs-json-render-react-pdf && rm -rf "$T"
manifest:
skills/react-pdf/SKILL.mdsource content
@json-render/react-pdf
React PDF renderer that generates PDF documents from JSON specs using
@react-pdf/renderer.
Installation
npm install @json-render/core @json-render/react-pdf
Quick Start
import { renderToBuffer } from "@json-render/react-pdf"; import type { Spec } from "@json-render/core"; const spec: Spec = { root: "doc", elements: { doc: { type: "Document", props: { title: "Invoice" }, children: ["page"] }, page: { type: "Page", props: { size: "A4" }, children: ["heading", "table"], }, heading: { type: "Heading", props: { text: "Invoice #1234", level: "h1" }, children: [], }, table: { type: "Table", props: { columns: [ { header: "Item", width: "60%" }, { header: "Price", width: "40%", align: "right" }, ], rows: [ ["Widget A", "$10.00"], ["Widget B", "$25.00"], ], }, children: [], }, }, }; const buffer = await renderToBuffer(spec);
Render APIs
import { renderToBuffer, renderToStream, renderToFile } from "@json-render/react-pdf"; // In-memory buffer const buffer = await renderToBuffer(spec); // Readable stream (pipe to HTTP response) const stream = await renderToStream(spec); stream.pipe(res); // Direct to file await renderToFile(spec, "./output.pdf");
All render functions accept an optional second argument:
{ registry?, state?, handlers? }.
Standard Components
| Component | Description |
|---|---|
| Top-level PDF wrapper (must be root) |
| Page with size (A4, LETTER), orientation, margins |
| Generic container (padding, margin, background, border) |
, | Flex layout with gap, align, justify |
| h1-h4 heading text |
| Body text (fontSize, color, weight, alignment) |
| Image from URL or base64 |
| Hyperlink with text and href |
| Data table with typed columns and rows |
| Ordered or unordered list |
| Horizontal line separator |
| Empty vertical space |
| Current page number and total pages |
Custom Catalog
import { defineCatalog } from "@json-render/core"; import { schema, defineRegistry, renderToBuffer } from "@json-render/react-pdf"; import { standardComponentDefinitions } from "@json-render/react-pdf/catalog"; import { z } from "zod"; const catalog = defineCatalog(schema, { components: { ...standardComponentDefinitions, Badge: { props: z.object({ label: z.string(), color: z.string().nullable() }), slots: [], description: "A colored badge label", }, }, actions: {}, }); const { registry } = defineRegistry(catalog, { components: { Badge: ({ props }) => ( <View style={{ backgroundColor: props.color ?? "#e5e7eb", padding: 4 }}> <Text>{props.label}</Text> </View> ), }, }); const buffer = await renderToBuffer(spec, { registry });
External Store (Controlled Mode)
Pass a
StateStore for full control over state:
import { createStateStore } from "@json-render/react-pdf"; const store = createStateStore({ invoice: { total: 100 } }); store.set("/invoice/total", 200);
Server-Safe Import
Import schema and catalog without pulling in React:
import { schema, standardComponentDefinitions } from "@json-render/react-pdf/server";