evanw / evanw/esbuild

[Bug]: tree shaking breaks with dynamic import() in some situation

Open
#4,255 1 comment 2 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
40.1k
Forks
1.3k
PR merge metrics
No merged PRs in 30d

Description

### System Info

```
System:
OS: macOS 15.5
CPU: (10) arm64 Apple M1 Max
Memory: 2.34 GB / 64.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 24.4.1 - ~/.volta/tools/image/node/24.4.1/bin/node
pnpm: 10.13.1 - ~/.volta/tools/image/pnpm/10.13.1/bin/pnpm
Watchman: 2025.07.28.00 - /opt/homebrew/bin/watchman
npmPackages:
esbuild: ^0.25.8 => 0.25.8
```

### Details

If you have a file `foo.ts` that contains 2 exports:

```ts
// foo.ts
export const bar = 'bar';
export const paz = 'paz';
```

Tree shaking will work (aka the unused variable will be stripped out during compilation) when writing:

```ts
// stripped.ts
import { bar } from './foo';
```

But if the file is lazy loaded using `import()`, `paz` is kept in the bundle:

```ts
// kept.ts
const { bar } = await import('./foo');
import('./foo').then(module => module.bar);
import('./foo').then(({ bar }) => bar);
```

The config I used is a simple one:
```json
{
"bundle": true,
"treeShaking": true,
"splitting": true,
"format": "esm",
"outdir": ".",
"write": false
}
```

### Reproduce link

https://github.com/Ayc0/code-splitting-issue

### Reproduce Steps

You can clone https://github.com/Ayc0/code-splitting-issue and run `node --test tests/esbuild.test.mjs` (requires node 24.4.0+)

Contributor guide

No contributing guide indexed for this repository

Research direction

Clone the linked code-splitting-issue repository and run node --test tests/esbuild.test.mjs with Node 24.4.0 or newer to reproduce the dynamic import cases. Compare the generated bundle with the static import case; done means the unused paz export is removed while bar remains available for each shown import pattern.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, javascript, node.js, typescript
Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.