vercel / vercel/next.js

Turbopack: support importing .ts/.tsx via .js extension (parity with webpack resolve.extensionAlias)

Open
#82,945 6 comments 28 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

linear: turbopack Module Resolution Turbopack
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!

PACK-5449

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.