Turbopack: support importing .ts/.tsx via .js extension (parity with webpack resolve.extensionAlias)
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 142k
- Forks
- 32.4k
- Avg merge
- 2d 14h
- Merged PRs (30d)
- 351
Description
Link to the code that reproduces this issue
https://github.com/jeremytenjo/startup-template/tree/convert-to-turbopack
To Reproduce
To Reproduce
Clone the repo above and switch to the convert-to-turbopack branch.
Install and start in dev:
npm i && npm run dev:nextjs
In the app, a file imports a module using a .js extension, e.g.:
// foo.js (import site-wide)
import { something } from "./bar.js";
where bar.ts (or bar.tsx) exists on disk, but no bar.js file.
With Turbopack enabled, the import fails to resolve to bar.ts/bar.tsx.
Note: With webpack, the equivalent works using:
// next.config.js -> webpack config
config.resolve.extensionAlias = {
".js": [".ts", ".tsx", ".js"],
};
but I can’t achieve the same behavior with Turbopack.
Current vs. Expected behavior
Current vs. Expected behavior
Current (Turbopack):
- Importing ./bar.js does not resolve to bar.ts/bar.tsx (only attempts real .js), resulting in a module resolution error during development.
Expected:
-
Parity with webpack’s resolve.extensionAlias so that imports written with .js seamlessly resolve to .ts/.tsx (and .js) in order:
- When a file on disk is bar.ts or bar.tsx, import "./bar.js" should resolve successfully to that file.
This is useful for mixed codebases, gradual TS adoption, or when libraries/app code keep .js import specifiers but the implementation is in TS.
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:40 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T8132
Available memory (MB): 24576
Available CPU cores: 10
Binaries:
Node: 20.18.2
npm: 11.5.2
Yarn: N/A
pnpm: N/A
Relevant Packages:
next: 15.5.0 // Latest available version is detected (15.5.0).
eslint-config-next: 13.1.0
react: 18.2.0
react-dom: 18.2.0
typescript: 5.2.2
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
Turbopack, Module Resolution
Which stage(s) are affected? (Select all that apply)
next dev (local)
Additional context
-
Goal is feature parity with webpack’s config.resolve.extensionAlias = { ".js": [".ts", ".tsx", ".js"] } so codebases can keep .js import specifiers while the implementation lives in TS.
-
I tried adjusting resolution-related settings per Turbopack docs (e.g., resolve extensions), but couldn’t achieve aliasing of an extension to multiple extensions.
-
Repro is local; no special hosting needed. Tested on macOS (Apple Silicon).
-
Happy to try an experimental flag or canary if there’s a hidden knob that enables this in Turbopack.
Thank you!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked startup-template reproduction, switch to the convert-to-turbopack branch, and run npm i && npm run dev:nextjs. Compare the failing ./bar.js import with the next.config.js webpack resolve.extensionAlias example. Done means Turbopack resolves that specifier to bar.ts, bar.tsx, or bar.js in the stated order.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, nextjs, typescript, webpack
- Domain
- build-system, devtools, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100