Skip to content

2.11.0: standard-fonts JSON imports missing "type: json" import attribute, breaks under plain Node ESM #156

Closed

Description

@shlomsh

Since 2.10.0/2.11.0 vendored @cantoo/standard-fonts, importing @cantoo/pdf-lib's ESM build under plain Node (not a bundler) throws:

Module ".../@cantoo/pdf-lib/es/packages/standard-fonts/Courier-Bold.compressed.json" needs an import attribute of "type: json"

Bundlers like Vite tolerate a bare import x from './foo.json', but Node's ESM loader requires with { type: 'json' } (or an equivalent import attribute) as of Node 22. This breaks any consumer that imports pdf-lib during a Node-executed SSR/prerender step rather than through a bundler — e.g. Astro's static-route generation, which runs built page modules directly under Node.

Repro:

node --input-type=module -e "import '@cantoo/pdf-lib'"

on 2.11.0 with Node 22.x.

2.9.1 didn't hit this since @cantoo/standard-fonts wasn't vendored as raw JSON imports yet.

Activity

  1. Sharcoux commented on Sep 15, 2026

    @Sharcoux
    Collaborator

    Can you check if 2.11.1 solves it?

  2. shlomsh commented on Sep 15, 2026

    @shlomsh
    Author

    Yes, 2.11.1 fixes it. Thanks for the quick turnaround.

    Checked on Node 24.13. The repro from the report now imports, embeds Helvetica and saves. 2.11.0 still throws ERR_IMPORT_ATTRIBUTE_MISSING in the same sandbox, so it's the version and not the environment. The Astro build that first hit this is green on 2.11.1 too.

    I also diffed the two npm tarballs to see what actually changed. It's the 14 *.compressed.json imports in es/packages/standard-fonts/Font.js plus all-encodings.compressed.json in Encoding.js, all now with { type: 'json' }, and no other JSON import is left under es/. That matches the failure exactly: cjs/ goes through require() and never needed the attribute, dist/ inlines the JSON so it has no .json references, and the ESM entry was the only path Node resolves file by file. Small fix, right scope.

    One thing worth knowing: with { ... } is the finalized syntax (Node 20.10+ and 22+). Node 18 only understood assert { ... }, but 18 is EOL, so that seems like the right trade.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions