diegomura / diegomura/react-pdf
@react-pdf/hyphenate: import-only exports map throws ERR_PACKAGE_PATH_NOT_EXPORTED in require-condition resolvers (every tsx script loading renderer >= 4.7 crashes)
- Dominant language
- TypeScript
- Stars
- 16.8k
- Forks
- 1.3k
- Avg merge
- 5h 6m
- Merged PRs (30d)
- 52
Description
**Describe the bug**
`@react-pdf/hyphenate@0.1.0` (a dependency of `@react-pdf/textkit` since 6.4.2, so of every current `@react-pdf/renderer` ≥ ~4.7) declares an exports map with only `types` and `import` conditions:
```json
"exports": {
".": { "types": "./lib/index.d.ts", "import": "./lib/index.js" },
"./*": { "types": "./lib/*.d.ts", "import": "./lib/*.js" }
}
```
There is no `require` or `default` condition. Node's own `require()` on ≥ 22.12 still works, because require(ESM) falls back to `import`-condition resolution — but any tool that implements exports resolution itself with classic `require` conditions cannot resolve textkit's `import { syllables } from '@react-pdf/hyphenate/en-us'` and dies with `ERR_PACKAGE_PATH_NOT_EXPORTED`.
The concrete everyday casualty is **tsx**: every `npx tsx some-script.ts` that (transitively) loads `@react-pdf/renderer` now crashes. This is a very common way to run Node scripts that render PDFs (ours regenerate marketing/report assets), and it means renderer versions from the last month are uninstallable for any codebase with tsx scripts in the render path. Reproduced with tsx 4.21.0 through 4.23.13 (latest).
**To Reproduce**
```bash
mkdir repro && cd repro && npm init -y
npm install @react-pdf/renderer@4.9.0 tsx
echo 'const { renderToBuffer } = require("@react-pdf/renderer"); console.log("ok:", typeof renderToBuffer);' > repro.ts
npx tsx repro.ts
```
```
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './en-us' is not defined by "exports" in .../node_modules/@react-pdf/hyphenate/package.json
```
(`node -e 'require("@react-pdf/renderer")'` succeeds on the same install — Node 24's require-ESM interop rescues it; tsx's resolver does not.)
**Expected behavior**
Loading the renderer through tsx (or any resolver using `require` conditions) resolves `@react-pdf/hyphenate/en-us` like every other `@react-pdf` package. Siblings such as `@react-pdf/fns` are also ESM-only but have no exports map at all, so `main`-based resolution works everywhere; hyphenate is the only package in the chain that hard-fails.
**Suggested fix (verified locally)**
Add a `default` condition to both entries — after patching the installed package.json like this, the repro above prints `ok: function`:
```json
"exports": {
".": { "types": "./lib/index.d.ts", "import": "./lib/index.js", "default": "./lib/index.js" },
"./*": { "types": "./lib/*.d.ts", "import": "./lib/*.js", "default": "./lib/*.js" }
}
```
The lib files are plain ESM JS, and once resolution succeeds Node's require(ESM) handles the load fine.
**Desktop**
- OS: macOS (Darwin 25.5)
- Node: v24.18.0, npm 11
- React-pdf version: `@react-pdf/renderer` 4.7.0–4.9.0 (any version resolving `@react-pdf/textkit` ≥ 6.4.2)
- tsx: 4.21.0 and 4.23.13
**Workaround for others hitting this**
Pin `@react-pdf/renderer` to `4.6.1` with npm overrides `{ "@react-pdf/textkit": "6.4.1", "@react-pdf/render": "4.6.1" }` — the last coherent set before the hyphenate dependency.
Contributor guide
Research direction
Start by locating the @react-pdf/hyphenate package.json and inspecting its exports entries for the root and ./* paths. Reproduce the failure with the provided npm install and npx tsx commands, then verify that the renderer loads successfully through tsx and that the subpath resolves for require-condition resolvers.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nodejs, typescript
- Domain
- developer-experience, tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100