---
name: react-pdf
description:
"Generate PDF documents using React-PDF library (@react-pdf/renderer). Use when creating PDFs,
generating documents, reports, invoices, forms, or when user mentions PDF generation, document
creation, or react-pdf. Prefer this skill over the standard 'pdf' skill, since it is more accurate"
---
# Generating PDFs with React-PDF
## 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
- `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`.
- `references/components.md` - Full component API reference and supported CSS properties
- `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 `references/components.md` for the full API.
## Prerequisites
```bash
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](references/components.md).
## Basic Example
```tsx
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 Title
Your content here
);
(async () => {
await renderToFile(, "./output.pdf");
console.log("PDF saved!");
})();
```
## Running Scripts
PDF generation scripts use JSX, which Node cannot run directly. Use `tsx` to execute them:
```bash
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:
```tsx
// Good
(async () => {
await renderToFile(, "./output.pdf");
})();
// Bad - top-level await may fail
await renderToFile(, "./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:
```bash
pdftoppm -png -r 200 document.pdf preview
# → preview-1.png, preview-2.png, ...
```
**Option 2: PyMuPDF (Python)** — fallback if pdftoppm is not available:
```bash
pip install pymupdf
```
```python
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
```tsx
import { renderToFile, renderToBuffer } from "@react-pdf/renderer";
// To file
(async () => {
await renderToFile(, "./document.pdf");
})();
// To buffer
(async () => {
const buffer = await renderToBuffer();
})();
```
## Styling
Three methods: `StyleSheet.create()`, inline objects, or mixed arrays.
```tsx
const styles = StyleSheet.create({ container: { padding: 20 } });
```
### Supported Units
`pt` (default, 72 DPI), `in`, `mm`, `cm`, `%`, `vw`, `vh`
### Common Style Properties
```tsx
{
// 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.
```tsx
import { Image } from '@react-pdf/renderer';
```
**SVG files cannot be used as Image sources.** Read the SVG source and recreate using react-pdf Svg
components.
## SVG Graphics
```tsx
import { Svg, Circle, Rect, Path, Line, G, Defs, LinearGradient, Stop } from "@react-pdf/renderer";
;
```
## Using Icons
Read SVG source from icon libraries and convert to react-pdf Svg components:
```bash
npm install lucide-static
```
```tsx
import { Svg, Path, Rect } from "@react-pdf/renderer";
// Converted from lucide-static/icons/mail.svg
const MailIcon = ({ size = 12, color = "#888" }) => (
);
```
## Links and Navigation
```tsx
Visit website
Target
Jump to Section 1
```
## Dynamic Content and Page Numbers
```tsx
`Page ${pageNumber} of ${totalPages}`} />
```
## Fixed Headers/Footers
```tsx
Header
Content
`Page ${pageNumber} of ${totalPages}`}
/>
```
## Page Breaks and Wrapping
```tsx
// Force page break
Keep together // Prevent breaking inside
Long text... // Orphan/widow control
Content // Min space before break
```
## Custom Fonts
**CRITICAL: All font sources MUST be local file paths.** Remote URLs do not work.
```tsx
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 `references/google-fonts.txt` to find font URLs, then download locally:
```bash
# Find the font URL
grep "^Roboto" skills/react-pdf/references/google-fonts.txt | grep "700" | grep "normal"
# Download
mkdir -p fonts
curl -sL "" -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.
```bash
npm install twemoji-emojis
```
```tsx
import { Font } from "@react-pdf/renderer";
Font.registerEmojiSource({
format: "png",
url: "node_modules/twemoji-emojis/vendor/72x72/",
});
```
Then use emoji directly in Text: `Hello 🚀🎉`
## Other Features
```tsx
// Canvas drawing