|
| 1 | +# Bun → Node.js Migration Plan |
| 2 | + |
| 3 | +Status: In progress. See below for completed and remaining steps. |
| 4 | + |
| 5 | +## Completed |
| 6 | + |
| 7 | +### Phase 4 (early): Package Manager Switch |
| 8 | +- [x] Changed `packageManager` from `bun@1.3.13` to `pnpm@10.11.0` |
| 9 | +- [x] Moved `patchedDependencies` into `pnpm` config section |
| 10 | +- [x] Added `onlyBuiltDependencies: ["esbuild"]` |
| 11 | +- [x] Added phantom deps as explicit devDependencies: `@sentry/core`, `@clack/prompts` |
| 12 | +- [x] Generated `pnpm-lock.yaml` |
| 13 | +- [x] Verified all patches apply (including cross-version: `@stricli/core@1.2.5` patch on `1.2.7`) |
| 14 | + |
| 15 | +### Phase 2, Group D: SQLite Adapter |
| 16 | +- [x] Created `src/lib/db/sqlite.ts` — runtime-detecting adapter (bun:sqlite under Bun, node:sqlite under Node.js) |
| 17 | +- [x] Updated 4 source files: `db/index.ts`, `schema.ts`, `migration.ts`, `utils.ts` |
| 18 | +- [x] Updated 3 test files: `fix.test.ts`, `telemetry.test.ts`, `schema.test.ts` |
| 19 | +- [x] Zero `bun:sqlite` imports remain in `src/` or `test/` |
| 20 | + |
| 21 | +## Remaining |
| 22 | + |
| 23 | +### Phase 2: Source Code Migration (replace Bun.* APIs in `src/`) |
| 24 | + |
| 25 | +**Group A: File I/O** — Replace `Bun.file()` / `Bun.write()` with `node:fs/promises` |
| 26 | +- `Bun.file(path).text()` → `readFile(path, "utf-8")` |
| 27 | +- `Bun.file(path).json()` → `readFile(path, "utf-8")` then `JSON.parse()` |
| 28 | +- `Bun.file(path).exists()` → `access(path).then(() => true, () => false)` |
| 29 | +- `Bun.write(path, content)` → `writeFile(path, content)` |
| 30 | +- Scan all of `src/` for occurrences |
| 31 | + |
| 32 | +**Group B: Process/System APIs** — Replace Bun.which / Bun.spawn / Bun.sleep |
| 33 | +- `Bun.which("cmd")` → `which` from a Node.js-compatible package or custom implementation |
| 34 | +- `Bun.spawn()` / `Bun.spawnSync()` → `child_process.spawn()` / `spawnSync()` |
| 35 | +- `Bun.sleep(ms)` → `setTimeout` promise wrapper |
| 36 | + |
| 37 | +**Group C: Miscellaneous Bun APIs** |
| 38 | +- `Bun.Glob` → `tinyglobby` or `picomatch` (already in devDependencies) |
| 39 | +- `Bun.randomUUIDv7()` → `uuidv7` package (already in devDependencies) |
| 40 | +- `Bun.semver.order()` → `semver.compare()` (already in devDependencies) |
| 41 | +- `Bun.zstdCompressSync()` / `Bun.zstdDecompressSync()` → Node.js zlib or `zstd-napi` package |
| 42 | + |
| 43 | +**Group E: Unpolyfilled APIs** |
| 44 | +- `bspatch.ts` and `upgrade.ts` — Replace any Bun-specific APIs not covered by node-polyfills.ts |
| 45 | + |
| 46 | +### Phase 3: Test Migration (`bun:test` → Vitest) |
| 47 | + |
| 48 | +- Add `vitest` as devDependency |
| 49 | +- Replace `import { ... } from "bun:test"` with Vitest equivalents |
| 50 | +- Replace `bun test` scripts with `vitest` |
| 51 | +- Key differences: |
| 52 | + - `bun:test`'s `mock.module()` → Vitest's `vi.mock()` |
| 53 | + - `bun:test`'s `spyOn` → Vitest's `vi.spyOn()` |
| 54 | + - Test file discovery patterns may differ |
| 55 | + - `--isolate --parallel` behavior needs Vitest equivalent |
| 56 | + |
| 57 | +### Phase 4: CI & Dev Scripts (remaining) |
| 58 | + |
| 59 | +- Update `package.json` scripts: `bun run` → `pnpm run` where appropriate |
| 60 | +- Replace `bun run src/bin.ts` with `tsx src/bin.ts` (add `tsx` devDependency) |
| 61 | +- Replace `bun run script/*.ts` with `tsx script/*.ts` |
| 62 | +- Replace `bunx` with `pnpm exec` |
| 63 | +- Update GitHub Actions workflows to use pnpm + Node.js instead of Bun |
| 64 | +- Update `Dockerfile` / build scripts if applicable |
| 65 | + |
| 66 | +### Phase 5: Cleanup |
| 67 | + |
| 68 | +- Remove `@types/bun` from devDependencies |
| 69 | +- Remove `bun.lock` (replaced by `pnpm-lock.yaml`) |
| 70 | +- Remove or update `script/node-polyfills.ts` (may become unnecessary) |
| 71 | +- Update `AGENTS.md` Bun API reference table |
| 72 | +- Remove Bun-specific `.cursor/rules/bun-cli.mdc` or update for Node.js |
| 73 | +- Clean up any remaining `Bun.*` references in comments/docs |
| 74 | + |
| 75 | +## Known Issues |
| 76 | + |
| 77 | +- `test/lib/index.test.ts` — `sdk.run throws when auth is required but missing` fails under pnpm's strict `node_modules`. The mock fetch returns empty 200s which prevents the expected auth error from being thrown. Pre-existing test fragility, not caused by migration changes. |
0 commit comments