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_threadsand most other built-ins load with or without thenode:prefix.- A module that default-exports
{ fetch }serves when run, as in Bun. Elide.serve({ port, fetch })takes the same Fetch-style handler asBun.serve.
Start with JavaScript and TypeScript. Module status is in the API Overview; suite results are in the Compatibility Matrix.
What changes
| Bun | Elide |
|---|---|
bun app.ts | elide app.ts |
bun install | elide install --ecosystems=npm; plain elide install skips npm |
bun.lock | aube-lock.yaml |
bun run build | elide run build |
bunx tool | elide run tool for a tool in node_modules/.bin; no download-and-run |
bun test with expect | elide test with node:test and node:assert; expect is unavailable |
bun --inspect app.ts | elide run --debugger=cdp app.ts |
bun --watch, bun --hot | No equivalent |
.env loaded automatically | Call process.loadEnvFile() in code |
Bun.serve({ fetch }) | Elide.serve({ fetch }) |
bun:sqlite | elide:sqlite; see Database modules |
Bun.file, Bun.write, Bun.$ | node:fs and node:child_process |
Web Worker | node:worker_threads |
bun build, bun build --compile | No equivalent |
Benchmarks
Startup: hyperfine -N -w 10 on a 24-core Linux workstation, running a hello-world script.
| Runtime | Command | Mean |
|---|---|---|
| Bun | bun hello.js | 1.8 ± 0.2 ms |
| Elide | elide run hello.js | 2.1 ± 0.1 ms |
| Node | node hello.js | 11.4 ± 0.8 ms |
| Deno | deno run hello.js | 6.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.
| Runtime | Requests/s | Mean latency |
|---|---|---|
| Bun | 147,742 | 1.70 ms |
| Elide | 600,352 | 419 µs |
| Deno | 280,666 | 0.89 ms |
| Node | 91,464 | 3.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.tsruns 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
Bunglobal, bundler, single-file executable, watch mode orexpectmatchers. - Node-API compatibility is 86.8% and WinterTC 95.9% on their test suites.
node:http2,node:cluster,node:inspectorandnode:wasithrowERR_UNKNOWN_BUILTIN_MODULE.https.createServerthrowsERR_HTTPS_SERVER_UNSUPPORTED, and there is noWebSocketglobal.- 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.
| Flag | Effect |
|---|---|
--sandbox | Deny 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=CMDS | Deny hosts or commands even when allowed. |
--fs-audit | Log each filesystem decision to stderr. |
--limit=workers=N, --limit=fds=N | Limit live workers and open node:fs handles. |
--max-mem=SIZE | Limit the heap size. |
--timeout=DURATION | Stop the run after DURATION with exit 124. |
elide --allow-read=. --allow-net=localhost --allow-run=git app.tsA 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.