Context
The extension is currently CommonJS. This blocks us from consuming a growing number of modern, ESM-only dependencies. Concrete recent example: p-limit@4+ is pure ESM, which is why #685 introduced an in-house ConcurrencyLimiter instead of pulling a battle-tested library off the shelf.
vscode-cosmosdb (sibling extension, same org) has already completed this migration on main, so there is a working reference for what the end state looks like.
What this issue tracks
The actual migration. The choice of build system, test runner, linter/formatter, and Node target is still to be made as part of this work. Options to evaluate:
- Build: Vite (what vscode-cosmosdb chose) vs. continuing with webpack in ESM mode vs. esbuild vs. tsup.
- Test runner: Vitest (what vscode-cosmosdb chose) vs. Jest with ESM support vs. node:test.
- Linter/formatter: continue with ESLint + Prettier vs. switch to oxlint / oxfmt (faster, what vscode-cosmosdb chose).
- Node engine: bump to >=22 (matches vscode-cosmosdb) or hold lower.
- TypeScript: bump to latest (vscode-cosmosdb is on TS 6.x).
A short design note before the implementation PR is expected.
Concrete benefits
- Unblocks ESM-only dependencies:
p-limit, chalk, node-fetch, nanoid, execa, and a long and growing tail.
- Smaller bundles and faster cold start (tree-shaking is much more effective on ESM).
- Faster build/test feedback loops if we adopt Vite + Vitest (sub-second incremental builds reported by vscode-cosmosdb).
- Aligns us with vscode-cosmosdb tooling, lowering the cognitive cost of moving between repos.
- Removes the mocha-based VS Code test runner pain point. The legacy
@vscode/test-electron + mocha pipeline does not love ESM; vscode-cosmosdb works around this with a pretest hook that drops a CJS package.json into out/. The upstream story is that this runner has either already been removed or is on track to be removed, so the workaround should be temporary or unnecessary depending on when we land.
Known costs / risks
- Touches every file with a relative import (
./foo -> ./foo.js in many ESM toolchains, depending on bundler/moduleResolution).
- Webpack config rewrite or replacement.
- Jest -> alternative test runner migration (touches every test file's imports and mocks;
jest.mock does not have a 1:1 ESM equivalent).
__dirname / require removal from the codebase.
- Potential VS Code engine version bump.
- One-shot reviewer load: the diff will be large.
References
Acceptance criteria
- Decision recorded for each open choice above.
- All existing tests pass under the new test runner (or a documented, scoped exception list).
- Extension activates, builds, packages, and ships exactly as before.
- CI green.
- No CJS-only fallback shims remaining (e.g. no
pretest-style package.json rewrite needed once the upstream test runner removal lands).
Context
The extension is currently CommonJS. This blocks us from consuming a growing number of modern, ESM-only dependencies. Concrete recent example:
p-limit@4+is pure ESM, which is why #685 introduced an in-houseConcurrencyLimiterinstead of pulling a battle-tested library off the shelf.vscode-cosmosdb(sibling extension, same org) has already completed this migration onmain, so there is a working reference for what the end state looks like.What this issue tracks
The actual migration. The choice of build system, test runner, linter/formatter, and Node target is still to be made as part of this work. Options to evaluate:
A short design note before the implementation PR is expected.
Concrete benefits
p-limit,chalk,node-fetch,nanoid,execa, and a long and growing tail.@vscode/test-electron+ mocha pipeline does not love ESM; vscode-cosmosdb works around this with apretesthook that drops a CJSpackage.jsonintoout/. The upstream story is that this runner has either already been removed or is on track to be removed, so the workaround should be temporary or unnecessary depending on when we land.Known costs / risks
./foo->./foo.jsin many ESM toolchains, depending on bundler/moduleResolution).jest.mockdoes not have a 1:1 ESM equivalent).__dirname/requireremoval from the codebase.References
package.jsonon main ("type": "module","main": "./main.mjs", Node >=22.18.0, Vite, Vitest, oxlint, oxfmt).Acceptance criteria
pretest-stylepackage.jsonrewrite needed once the upstream test runner removal lands).