Skip to content

ADR-002: Bun as Runtime, Test Runner, and Workspace Tool

Context

The project requires a JavaScript/TypeScript runtime, a test runner, a package manager, and a monorepo workspace tool. The monorepo contains multiple packages (language, cli, generator-emmett, syntax-highlighting, vscode, website) with inter-package dependencies.

Options evaluated:

DimensionNode.js + pnpm + VitestBun
RuntimeNode.jsBun (JavaScriptCore)
Package managerpnpmbun install
Workspacespnpm workspacesBun workspaces
Test runnerVitest or Jestbun:test
TS transpilationRequired (tsc/esbuild step)Native
Tool count3-4 separate tools1

Decision

Use Bun exclusively as runtime, test runner (bun:test), package manager, and workspace orchestrator. There is no Makefile. All build tasks are expressed as package.json scripts executed with bun run. Workspace-level commands run from the repository root.

TaskCommand
Run all testsbun test (workspace root)
Run package testsbun test (inside package dir)
Generate parserbun run langium:generate
Build docs sitebun run build (website/)

Consequences

Positive

  • Single binary handles all JS/TS concerns; no version matrix across tools.
  • Native TypeScript execution without a compile step reduces iteration time.
  • bun:test is API-compatible with Jest for basic assertions; migration cost is low.
  • Bun workspace resolution handles inter-package file: dependencies without symlink quirks.

Negative

  • Bun’s Node.js compatibility is high but not complete; edge cases may surface with Langium or esbuild plugins that rely on Node.js internals.
  • bun:test lacks some Vitest features (e.g., snapshot serializers); tests use only expect, describe, it, and test from the standard API.
  • Global rules referencing make targets do not apply to this project (documented in CLAUDE.md).