From react-pdf
Move a @react-pdf/renderer template to takumi-pdf by mapping each component and option, converting units, and registering fonts and images.
To migrate, replace react-pdf's primitives with HTML elements, move page settings into render() options, and convert lengths from pt to CSS px. The resulting JSX also renders as an image with takumi-js.
Before and after
// @react-pdf/renderer
import { Document, Page, View, Text, StyleSheet, renderToBuffer, Font } from "@react-pdf/renderer";
Font.register({ family: "Inter", src: "./Inter-Regular.ttf" });
const styles = StyleSheet.create({
page: { padding: 48, fontFamily: "Inter" },
row: { flexDirection: "row", justifyContent: "space-between" },
label: { fontSize: 10, color: "#6b7280" },
});
const pdf = await renderToBuffer(
<Document>
<Page size="A4" style={styles.page}>
<View style={styles.row}>
<Text style={styles.label}>Invoice</Text>
<Text style={styles.label}>INV-0042</Text>
</View>
</Page>
</Document>,
);// takumi-pdf
import { } from "@takumi-rs/helpers";
import { } from "takumi-pdf";
const = await (
< ="flex justify-between text-gray-500" ={{ : (10 * 96) / 72 }}>
<>Invoice</>
<>INV-0042</>
</>,
{ : "a4", : 64, : await (["Inter"]) },
);Component map
@react-pdf/renderer | takumi-pdf |
|---|---|
<Document> | none, since render() takes the tree |
<Page size="A4"> | the size option |
<View> | <div> |
<Text> | <span>, <p>, or bare text |
<Image src> | <img src> plus the images option |
<Link src> | <a href> |
<Svg> primitives | <svg>, or an SVG through images |
StyleSheet.create | style objects or tw classes |
Font.register | the fonts option |
renderToBuffer | render() returns a Uint8Array |
renderToStream, renderToFile | write the returned bytes yourself |
a fixed header or footer <View> | the header and footer options |
render={({ pageNumber, totalPages })} | <PageNumber /> and <TotalPages /> |
the break prop | break-before: page |
wrap={false} | break-inside: avoid |
orphans, widows | the same CSS properties |
minPresenceAhead | not supported |
Font.registerHyphenationCallback | not supported |
Font.registerEmojiSource | extractEmojis, then prepareImages |
<PDFViewer>, <PDFDownloadLink> | render bytes, then provide a preview or download |
Preserve the layout
Units are CSS px
react-pdf measures lengths in pt. Takumi measures them in CSS px at 96 dpi, so multiply every length by 96 / 72, about 1.333. A4 is 595 × 842 pt, or 794 × 1123 px. Unitless values such as flexGrow, opacity, and fontWeight carry over unchanged.
Flex direction defaults to row
react-pdf defaults every container to column. CSS defaults to row, so a stacked layout needs flex-direction: column written out.
Flex layout is opt-in
react-pdf's <View> is always a flex container. A plain HTML element is not, so a <div> that lays out children needs display: flex or display: grid. In Tailwind, write tw="flex flex-col".
Page bands
react-pdf repeats a band by marking a <View> inside the page as fixed. Takumi takes the band as a separate option and draws it in the margin:
import { } from "takumi-pdf";
import { , } from "takumi-pdf/primitives";
const = await (, {
: (
< ="flex w-full justify-center text-[10px] text-gray-500">
Page < /> of < />
</>
),
: { : 48, : 72 },
});The counter is a class on an element, not a render callback. See Headers & footers for counter styles and for sizing the margin to the band.
Assets load differently
The component map above shows where Font.register, <Image>, and Font.registerEmojiSource go.
Takumi does not use the 14 standard PDF fonts. Register every font your template uses.
See Fonts & images for the loaders.
Known gaps
Takumi has no equivalent for minPresenceAhead, hyphenation callbacks, or react-pdf's preview and download components. Render a Uint8Array and deliver it from your application. In a browser bundle, use the manual initialization entry. widows and orphans do work, as CSS properties, and Pagination covers them. For archival output and accessibility validation, see PDF/A & PDF/UA.
Last updated on