Skip to content

feat!: drop fs dependency from browser builds - #1763

Open
diegomura wants to merge 1 commit into
masterfrom
diegomura/drop-fs-browser-builds
Open

feat!: drop fs dependency from browser builds#1763
diegomura wants to merge 1 commit into
masterfrom
diegomura/drop-fs-browser-builds

Conversation

@diegomura

@diegomura diegomura commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

What kind of change does this PR introduce?

Browser builds no longer depend on fs.

Passing a file path to registerFont, image or file only works on Node now. Everywhere else those paths throw an error telling you to pass a Uint8Array, ArrayBuffer or data URL instead. The PDF/A ICC profile used to be read from disk with __dirname, so it never worked in a browser anyway. It is now inlined at build time.

This is part of modernizing the library. Bundlers no longer polyfill Node builtins by default, and we shouldn't expect users to configure polyfills to get a PDF out of the browser.

It also drops pdfkit/virtual-fs, which was already broken: the library calls fs APIs the virtual fs never implemented, so it fails as soon as you hit one of them.

This is the last thing blocking react-pdf from using pdfkit directly instead of its fork. That should bring roughly double the downloads to pdfkit.

@diegomura
diegomura force-pushed the diegomura/drop-fs-browser-builds branch from cd81fca to b463e24 Compare August 12, 2026 22:19
@diegomura diegomura changed the title Drop fs dependency from browser builds feat!: drop fs dependency from browser builds Aug 12, 2026
@diegomura
diegomura requested a review from blikblum August 12, 2026 22:21
@diegomura diegomura self-assigned this Aug 12, 2026
Comment thread lib/mixins/pdfa.js Outdated
@@ -1,4 +1,4 @@
import fs from 'fs';
import iccProfile from './data/sRGB_IEC61966_2_1.icc';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How it will behave on node?

It will load at library import?

We should try to keep the lazy loading approach

@diegomura diegomura Aug 12, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both node and browser behaves the same way. icc data is loaded as Uint8Array, converted in build time using binary rollup plugin.

We should try to keep the lazy loading approach

I think this is nice but how without fs?

@diegomura diegomura Aug 12, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decoding can be made lazy, but not loading. Feels like a very tiny optimization, but added it here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will take a look on how to keep the lazy loading behavior.

Comment thread package.json
},
"default": "./js/pdfkit.browser.mjs"
},
"./virtual-fs": {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets keep virtual fs for now. Is not bundled / used by default and does not hurt at all.

You can remove the usage in webpack

Having a vfs is the only way to register a globally accessible resource in browser.

So my idea is using one in browser #fs and exporting as vfs. This can be done later

@diegomura diegomura Aug 12, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dont mind restoring virtual fs but after this change what purpose would it serve if runtime doesn't actually use fs in browser?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we want for this library to be truly isomorphic we should stop relying on node deps at all, that includes virtual-fs workarounds

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think better. You can keep removal. I have another idea to provide a global file registration

@diegomura
diegomura force-pushed the diegomura/drop-fs-browser-builds branch 2 times, most recently from e490f2d to 53ba4b7 Compare August 12, 2026 23:05
@diegomura
diegomura requested a review from blikblum August 12, 2026 23:07
Browser bundles no longer import `fs`. File-path arguments to
`registerFont`, `image` and `file` now resolve through a `#fs` subpath
import that maps to Node's fs on Node and to a shim that throws a clear
error elsewhere.

The PDF/A sRGB ICC profile was read from disk via `__dirname`, which
never worked outside Node. It is now inlined at build time by a small
rollup/vite plugin that turns `.icc` imports into a `Uint8Array`.

Removes the virtual file system (`pdfkit/virtual-fs`), which was already
broken since the library uses fs APIs it does not implement, along with
the now unnecessary `brfs` transform and the runtime data copy step.
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.

2 participants