Compiled binaries
How Parley ships two self-contained Bun binaries with embedded migrations.
Parley ships two bun build --compile --bytecode binaries — parley (from @parley/cli) and parley-server (from @parley/api) — built independently. Each is a single self-contained file.
The server binary embeds its Drizzle migrations at build time via comptime.ts and auto-applies pending migrations on every parley-server run. See ADR 0008 for the rationale.
Build
bun run build:bin
# → packages/cli/dist/parley
# → packages/api/dist/parley-serverInstall
bun run install:bininstall:bin is strictly a symlink step — run build:bin first, or pass --build:
bun run install:bin -- --buildInstall target
The install target honors $XDG_BIN_HOME and falls back to ~/.local/bin. It:
- Refuses to overwrite a non-symlink at the target (so it won't blow away a
bun install -g-installedparley). - Replaces existing symlinks.
- Warns when the chosen directory isn't on
$PATH.
Adding a migration
After the binary already exists, the flow is two commands — no source edits:
bun --filter @parley/api db:generate
bun run build:binThe new migration is bundled into the next build of parley-server, and the next parley-server run applies it idempotently against the __drizzle_migrations table.
Why bytecode + embed
- One-file deploy. Operators ship
parley-server; nobun install, no migration sync step, no separate schema artifact. - Migrations travel with code. A binary version pins its migration set. Rolling back the binary rolls back the migrations applied by that binary; rolling forward applies any new ones.
- Bytecode startup.
--bytecodecuts cold-start parsing, which matters for the CLI:parley mcpis launched per-Claude-session.