Skip to content

Load standard fonts lazily via dynamic imports so a bundled Node build can render - #3571

Open
dbartholomae wants to merge 1 commit into
diegomura:masterfrom
dbartholomae:font/lazy-standard-fonts
Open

dbartholomae wants to merge 1 commit into
diegomura:masterfrom
dbartholomae:font/lazy-standard-fonts

Conversation

@dbartholomae

Copy link
Copy Markdown

Fixes #3570

What

@react-pdf/font loads each standard font's metrics through a dynamic import('pdfkit/standard-fonts/<Name>') the first time a document uses that face, and hands them to pdfkit through registerStdFonts before it opens the font. The static specifiers let a bundler carry the metrics along, and the dynamic import keeps them lazy in both the Node and the browser build. The browser build no longer registers all fourteen fonts at import.

@react-pdf/renderer awaits the font store's Helvetica load before it creates its PDFDocument, because pdfkit opens Helvetica in the document constructor, before any layout has loaded a font.

Why

pdfkit's Node build reads standard font metrics from a file beside its own module on first use. Bundled into another file it looks next to that file and finds nothing, and the Cannot find module '#standard-fonts/Helvetica' in #3570 is the result. The fix in the issue was to keep pdfkit external, which works but is a workaround for a package that otherwise bundles fine.

Depends on

pdfkit's Node build only exports registerStdFonts from the release that carries foliojs/pdfkit#1802 on. The code reads the export from the module namespace and does nothing when it is missing, so this is mergeable against pdfkit 0.20.x now: unbundled, pdfkit's own file loaders keep working as before, and the bundled case starts working once the pin moves to a pdfkit release that has the export. #3550 bumps the pin to 0.20.2, which does not yet have it.

Note for consumers: Font.getFont() for a standard font now returns data: null until Font.load() for that face has resolved, the same as for a registered font file.

Checked

Written with Claude Code, an AI assistant; the change was designed and verified in our own bundles as described above.

pdfkit's Node build reads each standard font's metrics from a file
beside its own module on first use, which a bundler cannot follow.
Load the metrics through dynamic imports with static specifiers and
register them with pdfkit before the font is opened, in the Node and
the browser build alike. The renderer waits for Helvetica before it
creates its document, because pdfkit opens Helvetica in the constructor.

Registration is skipped when pdfkit does not export registerStdFonts,
so this works against pdfkit 0.20.x today and starts to cover the
bundled case once the pin moves to a release carrying foliojs/pdfkit#1802.

Fixes diegomura#3570
@changeset-bot

changeset-bot Bot commented Sep 22, 2026

Copy link
Copy Markdown

馃 Changeset detected

Latest commit: 03b1c05

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 11 packages
Name Type
@react-pdf/font Patch
@react-pdf/renderer Patch
@react-pdf/types Patch
@react-pdf/math Patch
@react-pdf/mermaid Patch
@react-pdf/ui Patch
@react-pdf/examples Patch
@react-pdf/layout Patch
@react-pdf/render Patch
@react-pdf/stylesheet Patch
@react-pdf/tailwind Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel

vercel Bot commented Sep 22, 2026

Copy link
Copy Markdown

@dbartholomae is attempting to deploy a commit to the diegomura Team on Vercel.

A member of the Team first needs to authorize it.

@dbartholomae
dbartholomae marked this pull request as ready for review September 22, 2026 16:09

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Node build can't render once bundled: pdfkit reads its standard fonts from disk next to its own module

1 participant