Elide for Bun users

What works unchanged, which commands and APIs change, and how Elide compares with Bun.

Elide runs the TypeScript, node:* modules and npm packages a Bun program uses; the Bun global is absent.

Run the same code

elide app.ts                    # or: elide run app.ts
elide install --ecosystems=npm  # dependencies from package.json
elide test                      # node:test files
  • TypeScript runs with no compile step and no tsconfig.json.
  • node:fs, node:http, node:worker_threads and most other built-ins load with or without the node: prefix.
  • A module that default-exports { fetch } serves when run, as in Bun.
  • Elide.serve({ port, fetch }) takes the same Fetch-style handler as Bun.serve.

Start with JavaScript and TypeScript. Module status is in the API Overview; suite results are in the Compatibility Matrix.

What changes

BunElide
bun app.tselide app.ts
bun installelide install --ecosystems=npm; plain elide install skips npm
bun.lockaube-lock.yaml
bun run buildelide run build
bunx toolelide run tool for a tool in node_modules/.bin; no download-and-run
bun test with expectelide test with node:test and node:assert; expect is unavailable
bun --inspect app.tselide run --debugger=cdp app.ts
bun --watch, bun --hotNo equivalent
.env loaded automaticallyCall process.loadEnvFile() in code
Bun.serve({ fetch })Elide.serve({ fetch })
bun:sqliteelide:sqlite; see Database modules
Bun.file, Bun.write, Bun.$node:fs and node:child_process
Web Workernode:worker_threads
bun build, bun build --compileNo equivalent

Benchmarks

Startup: hyperfine -N -w 10 on a 24-core Linux workstation, running a hello-world script.

RuntimeCommandMean
Bunbun hello.js1.8 ± 0.2 ms
Elideelide run hello.js2.1 ± 0.1 ms
Nodenode hello.js11.4 ± 0.8 ms
Denodeno run hello.js6.1 ± 0.3 ms

Bun starts faster than Elide.

Serving: wrk -t12 -c256 -d10s against a hello-world server. Each server ran on the same 24 CPUs and wrk on 24 others.

RuntimeRequests/sMean latency
Bun147,7421.70 ms
Elide600,352419 µs
Deno280,6660.89 ms
Node91,4643.22 ms

Every server ran with its defaults: Bun, Deno and Node serve on one thread, Elide on several. This compares defaults, not tuned deployments.

Strengths

  • Served 600,352 requests per second against Bun’s 147,742, both with default settings.
  • elide serve --contexts=auto server.ts runs several copies of the app, sized from the CPU cores, on Linux.
  • Restricts filesystem, network and subprocess access with flags; Bun has no equivalent.
  • Limits workers, open files, heap and run time: --limit=workers=4, --limit=fds=128, --max-mem=512m, --timeout=30s.
  • The same binary runs WebAssembly, compiles and runs Java and Kotlin, and runs Python after elide setup python.

Weaknesses

  • Bun starts a hello-world script in 1.8 ms; Elide takes 2.1 ms.
  • No Bun global, bundler, single-file executable, watch mode or expect matchers.
  • Node-API compatibility is 86.8% and WinterTC 95.9% on their test suites.
  • node:http2, node:cluster, node:inspector and node:wasi throw ERR_UNKNOWN_BUILTIN_MODULE.
  • https.createServer throws ERR_HTTPS_SERVER_UNSUPPORTED, and there is no WebSocket global.
  • No macOS Intel build; macOS releases are Apple Silicon only.

Security model

Bun has no permission model: a script can read, write, connect and spawn anything your user can. Elide behaves the same until you pass a flag.

FlagEffect
--sandboxDeny filesystem access; network and subprocesses stay allowed.
--allow-read[=PATHS], --allow-write[=PATHS]Allow reads or writes, everywhere or at the listed paths.
--allow-net[=HOSTS]Allow network access, to every host or only the listed ones.
--allow-run[=CMDS]Allow subprocesses, any or only the listed commands.
--deny-net=HOSTS, --deny-run=CMDSDeny hosts or commands even when allowed.
--fs-auditLog each filesystem decision to stderr.
--limit=workers=N, --limit=fds=NLimit live workers and open node:fs handles.
--max-mem=SIZELimit the heap size.
--timeout=DURATIONStop the run after DURATION with exit 124.
elide --allow-read=. --allow-net=localhost --allow-run=git app.ts

A denied call names the flag to add:

TypeError: fetch to 'example.com:443' is not permitted; grant it with --allow-net=example.com

--sandbox=trusted is the only available profile. See Sandbox and Limits.

Next steps