Consider running llmlake under Node (keep writing Bun, ship a Node-runnable build)

Open
#2 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Quiet
Tech stack
bun, node.js, typescript
Domain
cli, tooling

Research direction

Start by reviewing the Bun-specific entry points named in build.ts, build-one.ts, status.ts, parse-session.ts, sync-pricing.ts, and collect.ts, then compare the four candidate approaches against the stated contributor and user goals. Done means the repository has a clear decision about Node support versus a standalone binary, with the runtime and DuckDB prerequisites accounted for.

Written by the indexing model from the issue text.

Description

Context

Today llmlake is Bun-only. Every *.ts entry point has a #!/usr/bin/env bun shebang and the llmlake dispatcher runs them with bun run. The shebang itself isn't the blocker — the scripts use Bun-native globals that simply don't exist in Node, so they'd throw Bun is not defined under node.

This issue is to consider whether we want a path to run under Node (lower barrier for contributors/users who don't have Bun), ideally without giving up writing Bun-style source.

What's Bun-specific today

The surface is small and well-contained:

  • Bun.spawn / Bun.spawnSync — duckdb processes (build.ts, build-one.ts, status.ts)
  • Bun.file(...).text() / .size — reading session/query files (parse-session.ts, build.ts, status.ts, sync-pricing.ts)
  • Bun.write — writing parquet temp JSON / pricing (build.ts, sync-pricing.ts)
  • Bun.Glob(...).scan(...) — finding jsonl files (parse-session.ts, build.ts)
  • Bun.hash — row ids (parse-session.ts)
  • Bun.$ shell — running collect scripts (collect.ts)
  • import.meta.dir — script-relative paths (most files; Node spells this import.meta.dirname)
  • navigator.hardwareConcurrency — build concurrency default (build.ts)

Candidate approaches

  1. Do nothing (status quo). Keep Bun as the documented prerequisite. It's a local dev tool and Bun install is one line. Lowest effort; this issue may just close as "won't do".

  2. Ship a standalone binary via bun build --compile. Bundles the Bun runtime into a single executable — users need neither Bun nor Node. Doesn't make it "run on Node" but solves the underlying "I don't have Bun" pain. Cost: per-platform builds + a release step.

  3. Bundle for a Node target + a thin Bun shim. Build with bun build --target=node (or esbuild) and provide a small compatibility module mapping the APIs above onto Node built-ins:

    • Bun.spawn/spawnSync → node:child_process
    • Bun.file().text()/.size → node:fs/promises
    • Bun.write → node:fs/promises
    • Bun.Glob().scan → node:fs glob / fast-glob
    • Bun.hash → node:crypto
    • Bun.$ → node:child_process (or drop in favor of plain spawns)
    • import.meta.dir → import.meta.dirname
    • navigator.hardwareConcurrency → node:os cpus().length

    Keeps the source Bun-flavored; the shim absorbs the difference. This is the "keep writing Bun but compile to Node" path.

  4. Refactor the Bun surface behind an internal runtime.ts with two implementations (Bun-native + Node) chosen at load. Cleaner than scattering shims, but more upfront refactor.

Notes / open questions

  • This is a deliberate, repo-wide decision, not a one-file change — status.ts just surfaced it.
  • DuckDB is an external prerequisite either way, so neither runtime removes that dependency.
  • Worth deciding the actual goal first: "contributors can use Node" (→ option 3/4) vs "users don't need a runtime at all" (→ option 2).

Low priority — capturing for later consideration.

Dominant language
TypeScript
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.