PluginBench
Skill
Official
Pass
Audit score 90

react-pdf

vercel-labs/json-render

Generate PDF documents from JSON specs using React components and @react-pdf/renderer.

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 programmatically generate PDFs from structured data, render to buffers/streams/files, or build custom PDF layouts with React components.

  • Render JSON specs to PDF buffers, streams, or files with three simple APIs
  • Support standard PDF components (Document, Page, Table, Text, Image, List, etc.)
  • Define custom components with Zod schemas and React implementations
  • Control state with external StateStore for dynamic content
  • Layout with flexbox (Row, Column) and spacing primitives
  • Generate multi-page documents with page numbers and headers/footers

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 dependencies: npm install @json-render/core @json-render/react-pdf
  2. 2.Define a JSON spec with root element and component tree (Document → Page → content)
  3. 3.Choose a render function: renderToBuffer (memory), renderToStream (HTTP), or renderToFile (disk)
  4. 4.Call the render function with your spec and optional registry/state/handlers
  5. 5.For custom components, define a catalog with Zod schemas and React implementations, then pass the registry to render

Use cases

Good for
  • Generate invoices, receipts, or reports from structured JSON data
  • Create dynamic PDF exports in web applications by piping streams to HTTP responses
  • Build reusable PDF templates with custom components and styling
  • Render tables and lists from database queries into formatted PDF documents
  • Generate certificates or documents with variable content from external state
Who it's for
  • Backend developers building PDF generation APIs
  • Full-stack developers adding PDF export features to web apps
  • Document automation engineers creating templated reports
  • Node.js/TypeScript developers working with json-render ecosystem

react-pdf FAQ

What's the difference between renderToBuffer, renderToStream, and renderToFile?

renderToBuffer returns a complete PDF in memory (best for small docs or APIs), renderToStream returns a readable stream (ideal for piping to HTTP responses), and renderToFile writes directly to disk (best for batch processing).

Can I use custom React components in my PDFs?

Yes. Define custom components in a catalog using Zod schemas for props validation, implement them as React components, and pass the registry to the render function.

How do I handle dynamic content in PDFs?

Use the optional state parameter when calling render functions, or create a StateStore with createStateStore for controlled state management across your spec.

Do I need React in my server environment?

No. Import from @json-render/react-pdf/server to access schema and catalog definitions without pulling in React dependencies.

What PDF page sizes and layouts are supported?

Page component supports standard sizes (A4, LETTER) and orientations (portrait, landscape), with configurable margins. Use Row/Column for flexbox layout and View for containers with padding, margins, and borders.

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:

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