PluginBench
Skill
Official
Pass
Audit score 90

react-pdf

vercel-labs/json-render

Render PDF documents from JSON specs using React components.

What is react-pdf?

@json-render/react-pdf is a React-based PDF renderer that converts JSON specifications into PDF documents. Use it when you need to generate PDFs programmatically from structured data, with support for layouts, tables, images, and custom components.

  • Render JSON specs to PDF buffers, streams, or files
  • Support standard components: Document, Page, View, Text, Heading, Table, Image, List, Link, and more
  • Define custom components with Zod schemas and React implementations
  • Control state with StateStore for dynamic content
  • Server-safe imports for schema and catalog without React dependencies

How to install react-pdf

npx skills add https://github.com/vercel-labs/json-render --skill react-pdf
Prerequisites
  • Node.js environment
  • npm or yarn package manager
  • @json-render/core and @json-render/react-pdf installed
Claude Code
Cursor
Windsurf
Cline

How to use react-pdf

  1. 1.Install @json-render/core and @json-render/react-pdf via npm
  2. 2.Define a JSON spec with a root element and component tree
  3. 3.Import renderToBuffer, renderToStream, or renderToFile from @json-render/react-pdf
  4. 4.Call the render function with your spec to generate PDF output
  5. 5.Optionally pass a registry with custom components or state store for dynamic content

Use cases

Good for
  • Generate invoices or receipts from order data
  • Create dynamic reports with tables and charts from JSON data
  • Build templated documents (certificates, contracts) from specifications
  • Render multi-page documents with headers, footers, and page numbers
  • Combine custom branded components with standard PDF layouts
Who it's for
  • Backend developers generating PDFs programmatically
  • Full-stack engineers building document generation features
  • Teams using json-render for declarative UI specifications
  • Applications needing server-side PDF rendering without browser dependencies

react-pdf FAQ

What render output formats are supported?

Three formats: renderToBuffer (in-memory Buffer), renderToStream (Readable stream for HTTP responses), and renderToFile (direct file write).

Can I use custom components beyond the standard set?

Yes, define custom components using defineCatalog and defineRegistry with Zod schemas, then pass the registry to render functions.

How do I handle dynamic content in PDFs?

Use createStateStore to manage state, pass it to render functions, and reference state paths in your JSON spec.

Is this safe to use on the server?

Yes, import from @json-render/react-pdf/server to get schema and catalog without pulling in React dependencies.

What page sizes and orientations are supported?

Page component supports standard sizes (A4, LETTER) and orientation settings via props.

Full instructions (SKILL.md)

Source of truth, from vercel-labs/json-render.


name: react-pdf description: 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.

@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

ComponentDescription
DocumentTop-level PDF wrapper (must be root)
PagePage with size (A4, LETTER), orientation, margins
ViewGeneric container (padding, margin, background, border)
Row, ColumnFlex layout with gap, align, justify
Headingh1-h4 heading text
TextBody text (fontSize, color, weight, alignment)
ImageImage from URL or base64
LinkHyperlink with text and href
TableData table with typed columns and rows
ListOrdered or unordered list
DividerHorizontal line separator
SpacerEmpty vertical space
PageNumberCurrent 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:

Nested lists can set repeat.statePath to { "$item": "field" } inside an enclosing repeat.

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";