Skip to content

resolve.tsconfigPaths misresolves paths from a symlinked shared tsconfig package #21856

Description

@luxass

Describe the bug

Vite 8 builtin resolve.tsconfigPaths resolves imports incorrectly when an app tsconfig.json extends a shared tsconfig package through a workspace symlink.

In the repro:

  • packages/app/tsconfig.json extends @repro/tsconfig/base
  • @repro/tsconfig is a workspace package symlinked into node_modules
  • the shared base config defines exact paths entries for:
    • @repro/shared-ui
    • @repro/shared-ui/components

These imports should resolve to source files via tsconfig paths:

  • @repro/shared-ui -> src/index.ts
  • @repro/shared-ui/components -> src/components/index.ts

Instead, with builtin resolve.tsconfigPaths, they resolve to package fallback targets:

  • @repro/shared-ui -> dist/index.js
  • @repro/shared-ui/components -> components.json

Using [email protected] in the same repo resolves both imports to source correctly.

The repro intentionally includes packages/shared-ui/components.json to make the incorrect fallback obvious. Without that file, the same broken resolution path would still not resolve to
source, and would instead fall back to dist/components/index.js.

A useful control case is included in the repro: if packages/app/tsconfig.json is changed to extend ../../tooling/tsconfig/base.json directly instead of @repro/tsconfig/base, builtin
resolve.tsconfigPaths also resolves both imports to source correctly.

So the issue appears to be specifically related to resolving extends through the symlinked tsconfig package path.

Reproduction

https://github.com/luxass/vite-tsconfig-repro

Steps to reproduce

  1. Run pnpm install
  2. Run cd packages/app
  3. Run pnpm dev:builtin
  4. Observe that the app renders:
{
  "expected": {
    "sharedUi": "src/index.ts",
    "sharedUiComponents": "src/components/index.ts"
  },
  "actual": {
    "sharedUi": "dist/index.js",
    "sharedUiComponents": "components.json"
  }
}
  1. Run pnpm dev:plugin
  2. Observe that the app resolves both imports to source correctly
  3. Optionally, in packages/app/tsconfig.json, comment:
    "extends": "@repro/tsconfig/base"
    and uncomment:
    "extends": "../../tooling/tsconfig/base.json"
  4. Run pnpm dev:builtin again
  5. Observe that builtin resolve.tsconfigPaths then resolves both imports to source correctly

System Info

System:
  OS: macOS 26.3
  CPU: (12) arm64 Apple M2 Max
  Memory: 225.20 MB / 32.00 GB
  Shell: 5.9 - /bin/zsh
Binaries:
  Node: 22.18.0 - /Users/[redacted]/.local/state/fnm_multishells/69591_1773470025327/bin/node
  npm: 10.9.3 - /Users/[redacted]/.local/state/fnm_multishells/69591_1773470025327/bin/npm
  pnpm: 10.32.1 - /Users/[redacted]/.local/state/fnm_multishells/69591_1773470025327/bin/pnpm
  bun: 1.3.10 - /opt/homebrew/bin/bun
  Deno: 2.7.5 - /opt/homebrew/bin/deno
Browsers:
  Chrome: 145.0.7632.160
  Firefox: 148.0
  Safari: 26.3
npmPackages:
  vite: 8.0.0 => 8.0.0

Used Package Manager

pnpm

Logs

No response

Validations

Metadata

Metadata

Assignees

Labels

bug: upstreamBug in a dependency of Vitehas workaroundp3-minor-bugAn edge case that only affects very specific usage (priority)

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions