MCPInstall

react-pdf

Generates PDF documents using the React-PDF library (@react-pdf/renderer) with TypeScript and JSX. Use when creating PDFs, generating reports, invoices, forms, resumes, or any document that needs flexbox layout, SVG graphics, custom fonts, or professional typesetting. Prefer over Python PDF libraries (ReportLab, fpdf2) when layout complexity matters.

Installs
85
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/trailofbits/skills-curated --skill react-pdf
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads react-pdf automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

Generating PDFs with React-PDF

When to Use

  • Generating PDF documents (reports, invoices, resumes, forms, certificates)
  • Creating PDFs that need complex layouts (multi-column, grids, cards)
  • Building PDFs with inline SVG graphics, charts, or icons
  • Producing documents with custom Google Fonts or emoji
  • Any PDF task where flexbox layout is easier than absolute coordinate math

When NOT to Use

  • Reading or extracting text from existing PDFs — use pdfplumber or pypdf instead
  • Filling existing PDF forms — use Python pypdf or pdftk
  • Converting HTML to PDF — use Playwright or WeasyPrint instead
  • Simple one-off text PDFs with no layout needs — a Python script may be simpler

CRITICAL REQUIREMENTS

  1. Fonts MUST be local files - Remote font URLs (http/https) do NOT work. Always download fonts to local files before using them.
  2. Wrap async code in IIFE - Top-level await causes errors. Always use (async () => { ... })() pattern.
  3. Disable hyphenation for custom fonts - Custom fonts lack hyphenation dictionaries and may crash or break words incorrectly. Always call Font.registerHyphenationCallback((word) => [word]); after registering custom fonts.

Files

  • {baseDir}/skills/react-pdf/references/google-fonts.txt - Metadata for ~65 popular Google Fonts with TrueType URLs. Each line is a font variant in tab-separated format: font name, style, category, weight, url.
  • {baseDir}/skills/react-pdf/references/components.md - Full component API reference and supported CSS properties
  • {baseDir}/skills/react-pdf/assets/example-template.tsx - Minimal working example demonstrating fixed footers, page numbers, and unbreakable content. Read this before starting to understand the basic patterns. Note: not all APIs are shown here — always refer to the docs and {baseDir}/skills/react-pdf/references/components.md for the full API.

Prerequisites

npm install react @react-pdf/renderer
npm install -D tsx @types/react

tsx runs TypeScript + JSX files directly via Node with no config — no tsconfig.json needed. It uses esbuild under the hood and handles JSX transformation automatically.

Core Components

  • Document: Root component (metadata, settings)
  • Page: Individual pages (A4, Letter, or custom dimensions)
  • View: Container component (similar to div)
  • Text: Text content, supports nesting for inline styling
  • Image: Embed images (JPG, PNG, base64)
  • Link: Clickable hyperlinks (external or internal)
  • Note: Annotation notes
  • Canvas: Freeform drawing with pdfkit methods
  • Svg: Vector graphics (Circle, Rect, Path, Line, Polygon, etc.)
  • StyleSheet: Create reusable styles

For full component props and CSS properties, see references/components.md.

Basic Example

import React from "react";
import { Document, Page, Text, View, StyleSheet, renderToFile } from "@react-pdf/renderer";

const styles = StyleSheet.create({
  page: { flexDirection: "column", backgroundColor: "#ffffff", padding: 40 },
  title: { fontSize: 24, marginBottom: 20, fontWeight: "bold" },
  text: { fontSize: 12, lineHeight: 1.5 },
});

const MyDocument = () => (
  <Document>
    <Page size="A4" style={styles.page}>
      <View style={{ margin: 10, padding: 20 }}>
        <Text style={styles.title}>Document Title</Text>
        <Text style={styles.text}>Your content here</Text>
      </View>
    </Page>
  </Document>
);

(async () => {
  await renderToFile(<MyDocument />, "./output.pdf");
  console.log("PDF saved!");
})();

Running Scripts

PDF generation scripts use JSX, which Node cannot run directly. Use tsx to execute them:

npx tsx my-document.tsx

npx tsx works without installing tsx globally — it downloads on demand. If tsx is installed as a dev dependency (npm install -D tsx), it runs instantly without the npx download step.

Always wrap rendering in async IIFE:

// Good
(async () => {
  await renderToFile(<MyDocument />, "./output.pdf");
})();

// Bad - top-level await may fail
await renderToFile(<MyDocument />, "./output.pdf");

Previewing PDFs

To visually inspect generated PDFs, convert pages to images. Try pdftoppm first (often pre-installed), fall back to Python's PyMuPDF if unavailable.

Option 1: pdftoppm (poppler-utils) — preferred, no install needed in many environments:

pdftoppm -png -r 200 document.pdf preview
# → preview-1.png, preview-2.png, ...

Option 2: PyMuPDF (Python) — fallback if pdftoppm is not available:

pip install pymupdf
import fitz

doc = fitz.open("document.pdf")
for i, page in enumerate(doc):
    pix = page.get_pixmap(dpi=200)
    pix.save(f"page-{i+1}.png")

Rendering Methods

import { renderToFile, renderToBuffer } from "@react-pdf/renderer";

// To file
(async () => {
  await renderToFile(<MyDocument />, "./document.pdf");
})();

// To buffer
(async () => {
  const buffer = await renderToBuffer(<MyDocument />);
})();

Styling

Three methods: StyleSheet.create(), inline objects, or mixed arrays.

const styles = StyleSheet.create({ container: { padding: 20 } });

<View style={styles.container} />
<View style={{ padding: 20 }} />
<View style={[styles.container, { marginTop: 10 }]} />

Supported Units

pt (default, 72 DPI), in, mm, cm, %, vw, vh

Common Style Properties

{
  // Flexbox
  flexDirection: "row", justifyContent: "space-between", alignItems: "center",
  flexWrap: "wrap", gap: 10,

  // Box model
  margin: 10, padding: 20, width: "100%", height: 200,

  // Borders
  borderWidth: 1, borderColor: "#333", borderRadius: 5, borderStyle: "solid",

  // Colors
  backgroundColor: "#f0f0f0", color: "#000", opacity: 0.8,

  // Typography
  fontSize: 12, fontWeight: "bold", fontFamily: "Helvetica", fontStyle: "italic",
  lineHeight: 1.5, textAlign: "center", textDecoration: "underline",
  textTransform: "uppercase", letterSpacing: 1,

  // Position
  position: "absolute", top: 0, left: 0, right: 0, bottom: 0, zIndex: 10,

  // Transforms
  transform: "rotate(45deg)", transformOrigin: "center",
}

Images

Local files are most reliable. Remote URLs may fail due to network/CORS issues.

import { Image } from '@react-pdf/renderer';

<Image src="./images/photo.jpg" style={{ width: 200, height: 150 }} />
<Image src={{ data: buffer, format: 'png' }} />

SVG files cannot be used as Image sources. Read the SVG source and recreate using react-pdf Svg components.

SVG Graphics

import { Svg, Circle, Rect, Path, Line, G, Defs, LinearGradient, Stop } from "@react-pdf/renderer";

<Svg width="200" height="200" viewBox="0 0 200 200">
  <Defs>
    <LinearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <Stop offset="0%" stopColor="#3498db" />
      <Stop offset="100%" stopColor="#9b59b6" />
    </LinearGradient>
  </Defs>
  <Circle cx="100" cy="100" r="50" fill="url(#grad1)" />
  <Rect x="10" y="10" width="50" height="50" fill="#e74c3c" />
  <Path d="M10,50 Q50,10 90,50" stroke="#2ecc71" strokeWidth="2" fill="none" />
</Svg>;

Using Icons

Read SVG source from icon libraries and convert to react-pdf Svg components:

npm install lucide-static
import { Svg, Path, Rect } from "@react-pdf/renderer";

// Converted from lucide-static/icons/mail.svg
const MailIcon = ({ size = 12, color = "#888" }) => (
  <Svg width={size} height={size} viewBox="0 0 24 24">
    <Path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" stroke={color} strokeWidth={2} fill="none" />
    <Rect x="2" y="4" width="20" height="16" rx="2" stroke={color} strokeWidth={2} fill="none" />
  </Svg>
);

Links and Navigation

<Link src="https://example.com"><Text>Visit website</Text></Link>

<View id="section-1"><Text>Target</Text></View>
<Link src="#section-1"><Text>Jump to Section 1</Text></Link>

Dynamic Content and Page Numbers

<Text render={({ pageNumber, totalPages }) => `Page ${pageNumber} of ${totalPages}`} />

Fixed Headers/Footers

<Page size="A4">
  <View fixed style={{ position: "absolute", top: 20, left: 30, right: 30 }}>
    <Text>Header</Text>
  </View>
  <View style={{ marginTop: 60, marginBottom: 60 }}>
    <Text>Content</Text>
  </View>
  <Text
    fixed
    style={{ position: "absolute", bottom: 20, left: 30, right: 30, textAlign: "center" }}
    render={({ pageNumber, totalPages }) => `Page ${pageNumber} of ${totalPages}`}
  />
</Page>

Page Breaks and Wrapping

<View break />                              // Force page break
<View wrap={false}><Text>Keep together</Text></View>  // Prevent breaking inside
<Text orphans={2} widows={2}>Long text...</Text>       // Orphan/widow control
<View minPresenceAhead={100}><Text>Content</Text></View>  // Min space before break

Custom Fonts

CRITICAL: All font sources MUST be local file paths. Remote URLs do not work.

import { Font } from "@react-pdf/renderer";

Font.register({
  family: "Roboto",
  fonts: [
    { src: "./fonts/Roboto-Regular.ttf", fontWeight: "normal" },
    { src: "./fonts/Roboto-Bold.ttf", fontWeight: "bold" },
    { src: "./fonts/Roboto-Italic.ttf", fontStyle: "italic" },
  ],
});

// Always disable hyphenation when using custom fonts
Font.registerHyphenationCallback((word) => [word]);

Built-in fonts: Courier, Helvetica, Times-Roman (each with Bold, Italic/Oblique variants)

Font weight values: thin (100), ultralight (200), light (300), normal (400), medium (500), semibold (600), bold (700), ultrabold (800), heavy (900)

Google Fonts

Use {baseDir}/skills/react-pdf/references/google-fonts.txt to find font URLs, then download locally:

# Find the font URL
grep "^Roboto" {baseDir}/skills/react-pdf/references/google-fonts.txt | grep "700" | grep "normal"

# Download
mkdir -p fonts
curl -sL "<url-from-grep>" -o fonts/Roboto-Bold.ttf

# Verify - must show "TrueType Font data"
file fonts/Roboto-Bold.ttf

If file shows "HTML document" or "ASCII text", the download failed. Try a different URL or search GitHub for the font's official repo with TTF files.

Emoji

Emoji won't render in PDFs unless you register an emoji source. Install twemoji-emojis to get local Twemoji PNG assets — no internet needed at render time.

npm install twemoji-emojis
import { Font } from "@react-pdf/renderer";

Font.registerEmojiSource({
  format: "png",
  url: "node_modules/twemoji-emojis/vendor/72x72/",
});

Then use emoji directly in Text: <Text>Hello</Text>

Other Features

// Canvas drawing
<Canvas style={{ width: 200, height: 200 }}
  paint={(painter, w, h) => { painter.circle(w/2, h/2, 50).fill("#3498db"); }} />

// Annotation notes
<Note style={{ color: "yellow" }}>Annotation text</Note>

// Hyphenation
Font.registerHyphenationCallback((word) => [word]); // disable

// Debug mode - visualize boundaries
<View debug><Text debug>Debug text</Text></View>

// Document metadata
<Document title="My Doc" author="Author" subject="Report" language="en-US" pdfVersion="1.5" />

Best Practices

  1. Use StyleSheet.create() — define styles once and reuse
  2. Compress images before embedding, use cache={true} for remote images
  3. Test page breaks — content may flow differently than expected
  4. Prefer flexbox over absolute positioning
  5. Use fixed prop for headers/footers on every page
  6. Use debug={true} to visualize element boundaries
  7. Wrap rendering in try-catch blocks

Common Issues

Text overflow: <Text style={{ width: 200, maxLines: 3, textOverflow: "ellipsis" }}>...</Text>

Missing fonts: Download locally and register with local file paths. Remote URLs will NOT work.

Unexpected page breaks: Use wrap={false} to keep content together, or <View break /> to force breaks.

FAQ

What does the react-pdf skill do?

Generates PDF documents using the React-PDF library (@react-pdf/renderer) with TypeScript and JSX. Use when creating PDFs, generating reports, invoices, forms, resumes, or any document that needs flexbox layout, SVG graphics, custom fonts, or professional typesetting. Prefer over Python PDF libraries (ReportLab, fpdf2) when layout complexity matters.

How do I install react-pdf?

Run npx skills add https://github.com/trailofbits/skills-curated --skill react-pdf in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/react-pdf/ (personal) or .claude/skills/react-pdf/ (project).

Which AI agents can use react-pdf?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is react-pdf safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains react-pdf?

It is published by trailofbits in trailofbits/skills-curated. It has 85 recorded installs.

More from trailofbits/skills-curated

View all →

ghidra-headless

trailofbits/skills-curated

Reverse engineers binaries using Ghidra's headless analyzer. Use when decompiling executables, extracting functions, strings, symbols, or analyzing call graphs from compiled binaries without the Ghidra GUI.

510 installs

humanizer

trailofbits/skills-curated

Remove signs of AI-generated writing from text. Use when editing or reviewing text to make it sound more natural and human-written. Based on Wikipedia's comprehensive "Signs of AI writing" guide. Detects and fixes patterns including: inflated symbolism, promotional language, superficial -ing analyses, vague attributions, em dash overuse, rule of three, AI vocabulary words, negative parallelisms, and excessive conjunctive phrases. 30c5c8d (Update humanizer plugin to upstream v2.2.0)

Docs & Writing207 installs

skill-extractor

trailofbits/skills-curated

Extracts reusable skills from work sessions. Use when: (1) a non-obvious problem was solved worth preserving, (2) a pattern was discovered that would help future sessions, (3) a workaround or debugging technique needs documentation. Manual invocation only via /skill-extractor command - no automatic triggers or hooks.

openai-develop-web-game

trailofbits/skills-curated

Use when the agent is building or iterating on a web game (HTML/JS) and needs a reliable development + testing loop: implement small changes, run a Playwright-based test script with short input bursts and intentional pauses, inspect screenshots/text, and review console errors with rendergametotext. Originally from OpenAI's curated skills catalog.

Media & Creative134 installs

planning-with-files

trailofbits/skills-curated

Open the skill to read its SKILL.md instructions.

security-awareness

trailofbits/skills-curated

Teaches agents to recognize and avoid security threats during normal activity. Covers phishing detection, credential protection, domain verification, and social engineering defense. Use when building or operating agents that access email, credential vaults, web browsers, or sensitive data.

Security125 installs

Popular frontend & design skills

View category →

setup-matt-pocock-skills

mattpocock/skills

Configure this repo for the engineering skills: set up its issue tracker, triage label vocabulary, and domain doc layout. Run once before first use of the other engineering skills.

Frontend & Design1.1M installs

frontend-design

anthropics/skills

Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.

OfficialFrontend & Design1M installs

hyperframes-animation

heygen-com/hyperframes

All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus Lottie, Three.js, Anime.js, CSS keyframes, Web Animations API, TypeGPU). Use for any motion or animation task: pick 2-4 rules and compose, or load a blueprint, or look up runtime-specific API (e.g. GSAP eases / Lottie player / Three.js mixer). Also covers auditing an existing composition's choreography (animation map) and 24 named text-animation effects. HyperFrames-native: single paused timeline, seek-safe, deterministic.

prototype

mattpocock/skills

Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.

Frontend & Design999.2K installs

hyperframes-core

heygen-com/hyperframes

The HyperFrames composition contract — build one renderable project. Use for composition structure, the data- timing attributes, class="clip", tracks, sub-compositions, variables, framework-owned media playback, deterministic-render rules, and validation. Read before writing composition HTML.

Frontend & Design930.5K installs

vercel-react-best-practices

vercel-labs/agent-skills

React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.

OfficialFrontend & Design843.1K installs