react-pdf alternative · measured
What jasy does differently.
react-pdf is the established way to build PDFs from components, and a good one. Every library makes choices, and some choices set natural limits. This page shows where jasy chose differently - measured against react-pdf 4.9.0 on November 8, 2026, each result with the code that produces it. Where react-pdf has caught up, it is not on this page.
Five places where jasy works differently
01
Password protection
Set a password and both encrypt the file. The difference is what you get without setting anything else.
- react-pdf 4.9.0
- By default 40-bit RC4 (/V 1, /R 2) in a PDF 1.3 file. AES-256 is there with pdfVersion: "1.7ext3" - in revision 5, Adobe's pre-standard version that ISO 32000-2 deprecates.
- jasy
- Always AES-256 in revision 6 (/V 5, /R 6), the current handler of ISO 32000-2 - no option to know about, and nothing weaker.
PDFKit, which react-pdf builds on, does the same by default (0.20.2).
Reproduce it
// react-pdf 4.9.0
<Document userPassword="secret">...</Document>
// %PDF-1.3 ... /Encrypt << /V 1 /R 2 >> 40-bit RC4
<Document userPassword="secret" pdfVersion="1.7ext3">...</Document>
// %PDF-1.7 ... /Encrypt << /V 5 /R 5 >> /AESV3 AES-256, revision 5
// jasy
await renderToBytes(doc, { encrypt: { userPassword: "secret" } });
// %PDF-2.0 ... /Encrypt << /V 5 /R 6 >> /AESV3 AES-25602
Accessible, tagged PDFs
A screen reader needs a structure tree: what is a heading, what is a paragraph, what is decoration.
- react-pdf 4.9.0
- react-pdf has no option for a structure tree. veraPDF's PDF/UA-1 check reports 4 failed rules, among them the missing StructTreeRoot and MarkInfo.
- jasy
- accessible: true writes a tagged PDF/UA-1 file. veraPDF: 0 failed rules.
Reproduce it
// react-pdf 4.9.0 - title and language, but no structure tree
<Document title="Quarterly report" language="en-US">...</Document>
// verapdf -f ua1: not compliant, 4 failed rules
// jasy
Text("Quarterly report", { role: "h1" });
await renderToBytes(doc, { accessible: true, title: "Quarterly report", lang: "en-US" });
// verapdf -f ua1: compliant, 0 failed rules03
SVG with styles, as Illustrator exports it
Illustrator's default SVG export puts the colors into a style block as CSS classes.
- react-pdf 4.9.0
- The CSS classes are not applied, so the shapes stay invisible - without a message.
- jasy
- Both shapes, in their colors, as vectors.
(nothing drawn)


Reproduce it
<!-- styled.svg, as Illustrator's "Internal CSS" export writes it -->
<svg viewBox="0 0 120 60"><defs><style>.cls-1{fill:#e2483d}.cls-2{fill:#1450aa}</style></defs>
<rect class="cls-1" width="55" height="60"/><circle class="cls-2" cx="90" cy="30" r="28"/></svg>
// react-pdf 4.9.0
<Image src="styled.svg" style={{ width: 120 }} />
// jasy
Image("styled.svg", { width: 120 });04
German hyphenation
In a narrow column, long German words have to be broken. react-pdf ships English hyphenation patterns and applies them to every language.
- react-pdf 4.9.0
- react-pdf
- jasy
- jasy with German patterns
| Word | react-pdf 4.9.0 | jasy with German patterns |
|---|---|---|
| Urinstinkt (40 pt) | Urin- | stinkt | Ur- | instinkt |
| Umsatzsteueridentifikationsnummer (100 pt) | Umsatzsteueri- | dentifikationsnum- | mer | Umsatzsteuer- | identifikationsnum- | mer |
jasy does not hyphenate until you name the language - one line with any pattern library, here hyphen/de. The last word is on every German invoice.
Reproduce it
// react-pdf 4.9.0: a narrow column, nothing configured
<View style={{ width: 100 }}><Text>Umsatzsteueridentifikationsnummer</Text></View>
// jasy, with German patterns
import { hyphenateSync } from "hyphen/de";
const hyphenate = (word: string) => hyphenateSync(word).split("\u00AD");
Box({ width: 100 }, [Text("Umsatzsteueridentifikationsnummer", { hyphenate })]);05
A paragraph that does not fit the page
Large type on a small page - a label, a ticket - can leave a paragraph that fits on no page at all.
- react-pdf 4.9.0
- There is no stop condition for this case: the process keeps going until it runs out of memory.
- jasy
- A named error after milliseconds, saying what to change - or, with onOverflow: "warn", a clipped render and a warning.
Reproduce it
// react-pdf 4.9.0: two lines of 34pt text, 50pt of room
<Page size={[420, 90]} style={{ padding: 20 }}>
<Text style={{ fontSize: 34 }}>Typography, jumping quickly</Text>
</Page>
// FATAL ERROR: ... JavaScript heap out of memory
// jasy: the same page
// Layout overflow: Text is 79pt tall but the page region is only 50pt and it cannot be
// broken - reduce its size, give it a bounded height, or let it split across pages.What only jasy does
Fill PDFs that already exist
Open a form someone else made - a government PDF, a supplier's order sheet - fill it, flatten it, also when it is encrypted. react-pdf only creates PDFs.
E-invoices: ZUGFeRD and XRechnung
The PDF/A-3 with the EN 16931 XML inside, computed totals, and the check against the official rules. react-pdf cannot embed the XML.
Vue and Nuxt, not only React
The same engine as Vue components, as a Nuxt module, as React components or as plain functions.
Color emoji as vectors
Drawn from a COLR color font, sharp at any zoom. react-pdf embeds one bitmap image per emoji.
3.6× faster on average
Six documents, same text, same pages - measured against react-pdf 4.9.0.
Where react-pdf is level, or ahead
- Both create form fields (text, checkbox, select).
- Both draw an SVG file through the image component.
- Both write PDF/A-3b - react-pdf once you register an embedded font; with its default font veraPDF fails it.
- Both produce the same bytes twice - react-pdf when you pin creationDate.
- react-pdf has years in production and a large community. jasy is in beta.
Claims we used to make and dropped after re-measuring: react-pdf now refuses a borderRadius in percent instead of misdrawing it, and draws SVG through its Image component.
How we measured: the latest react-pdf from npm, pdftoppm to look at the result, veraPDF for PDF/A and PDF/UA. Every snippet on this page is the test.