mirror of
https://github.com/anomalyco/opentui.git
synced 2026-04-25 13:06:00 +03:00
[GH-ISSUE #504] TypeScript NodeNext resolution fails with extensionless re-exports #900
Labels
No labels
bug
core
documentation
feature
good first issue
help wanted
pull-request
question
react
solid
tmux
windows
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/opentui#900
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @schickling on GitHub (Jan 9, 2026).
Original GitHub issue: https://github.com/anomalyco/opentui/issues/504
Summary
TypeScript NodeNext module resolution can’t resolve OpenTUI’s extensionless re-exports from its declaration files, which hides exported APIs like
createCliRendererandcreateRoot.Details
index.d.tscontainsexport * from "./renderer"src/index.d.tscontainsexport * from "./reconciler/renderer"With TS 5.9 and
moduleResolution: "NodeNext",tsc --traceResolutionreports “Module name './renderer' was not resolved” even thoughrenderer.d.tsexists. This results in TS2305 (“no exported member”).Repro
Workaround
Use
moduleResolution: "Bundler"in the consumer tsconfig so TS accepts extensionless re-exports.Request
Consider adding explicit extensions in declaration re-exports (e.g.
./renderer.js/./reconciler/renderer.js) or adjusting the packageexportsso NodeNext resolution works without the Bundler override.Opened on behalf of @schickling via Codex CLI.
@remorses commented on GitHub (Jan 9, 2026):
Simply add in tsconfig.json
skipLibCheck: true.@schickling commented on GitHub (Feb 1, 2026):
Unfortunately
skipLibCheck: truedoesn't solve this issue. The problem is that TypeScript still needs to resolve module exports to understand what the library provides -skipLibCheckonly skips type checking inside.d.tsfiles, not the resolution of re-exports.Minimal repro demonstrating this: https://github.com/schickling-repros/opentui-nodenext-issue
With
skipLibCheck: trueenabled, you still get:The fix needs to be in the library itself - adding explicit
.jsextensions to the re-exports in the.d.tsfiles.@schickling commented on GitHub (Feb 1, 2026):
Submitted a fix: #614
The PR adds
.jsextensions to all relative imports/exports in the.d.tsfiles, which allows TypeScript'smoduleResolution: "NodeNext"to resolve the exports correctly.@remorses commented on GitHub (Feb 1, 2026):
What are you trying to accomplish? Opentui does not support Node.js so you would still be unable to use it. Instead you could switch to Bundler resolver
@schickling commented on GitHub (Feb 1, 2026):
Good question! We do use OpenTUI with Bun at runtime. The
module: "NodeNext"/moduleResolution: "NodeNext"configuration is orthogonal to the runtime — it is the strictest TypeScript module resolution mode and we use it as a best practice across all our packages regardless of whether the code runs on Node.js or Bun. It ensures correct ESM semantics and catches module resolution issues at compile time.Switching to
"Bundler"would work around this, but it is a less strict mode that can mask real issues, so we would prefer not to relax our tsconfig for a single dependency. The fix in #614 is small (just adding.jsextensions to the re-exports in.d.tsfiles) and would make OpenTUI compatible with all resolution modes.