DocumentsDosu Decant
History: the Rust/Elixir/Swift to TypeScript cutover (2026-07)
History: the Rust/Elixir/Swift to TypeScript cutover (2026-07)
Type
Document
Status
Published
Created
Aug 3, 2026
Updated
Aug 3, 2026

History: the Rust/Elixir/Swift → TypeScript cutover (2026-07)#

Context for why decant is a single Bun + TypeScript app and why the project
invariants read the way they do. Written 2026-08-03 from the migration
records.

What existed before#

Until 2026-07-04, decant was three coupled apps: Rust crates (parsers, ingest,
a background daemon that owned the SQLite archive), a Phoenix (Elixir) web
UI talking to the daemon behind a bearer-token API, and a Swift macOS menu
bar app. The pre-cutover tree is preserved in the signed pre-typescript
tag.

The decision#

The stated optimization target was contributor accessibility for AI
developers
— one language, one process, one repo-root app. Enabling spikes
happened 2026-07-02 (Bun's bun:sqlite FTS5 support passed; Bun fullstack
HTML imports chosen over Vite so bun build --compile can ship single
binaries embedding the UI). The macOS app was dropped at cutover.

How it landed#

PR #20 carried the entire migration in one PR (284 files, +16k/−40k),
deleting crates/, web/, and macos/; merged to main 2026-07-04 together
with #22 (UI parity). Follow-up audits on 2026-07-04 and 2026-07-06 verified
the punch-list items were resolved in code (server request guards, ingest
test restoration, release workflow, UI parity items).

Durable decisions that trace to the cutover#

  • One process owns SQLite (invariant 2): the daemon/token/second-app
    architecture is what the cutover removed; do not reintroduce it.
  • Core modules stay print-free (invariant 1) — output policy lives in
    src/cli.ts.
  • npm distribution uses the optionalDependencies platform-package pattern
    (launcher .cjs shim + per-platform compiled binaries) because npx runs
    under Node while the app needs bun:sqlite.
  • Toolchain: Bun runtime, Biome, commander, native fs.watch plus a sweep
    (Bun's watcher needed a 2026-04 upstream fix for new subdirectories on
    Linux).
  • The golden-parity oracle (test/golden/) predates the cutover: it was the
    byte-determinism harness proving the TS port matched the Rust behavior, and
    it remains the regression net for parser changes.

Useful archaeology pointers#

  • pre-typescript (signed tag): the last pre-cutover commit; the old Rust
    schema tracked versions 1–8 in schema_migrations, which is why pre-v8
    archives are rebuild-only today.
  • The npm scope decision (@dosu/decant, no plan to claim unscoped
    decant) dates to the same period.