our tooling is a waste of time
most javascript developers have stockholm syndrome. we have spent years convincing ourselves that having a 200mb node_modules folder and a brittle chain of transpilers, bundlers, and test runners is just the cost of doing business.
it isn't. i recently dug into this and realized our tooling has been holding us back:
the bloat is optional
node is a general-purpose runtime that was never built for the modern typescript era. to get anything done, you need a package manager, a compiler, a bundler, and a tester.
bun replaces all of them. it is written in zig and uses the javascriptcore engine. it starts up in milliseconds because it does not have a decade of legacy debt. you can launch a full-stack server with zero external dependencies:
const server = Bun.serve({
port: 3000,
fetch(req) {
return new Response("hello world");
},
});
console.log(`listening on http://localhost:${server.port}`);
batteries included means no more glue code
the most frustrating part of web dev is writing glue code to make tools talk to each other. bun handles this natively.
- native typescript: you run .ts and .tsx files directly. no build step. no source map headaches.
- built-in sqlite: you do not need a heavy database container for simple projects or clis.
import { Database } from "bun:sqlite";
const db = new Database("data.db");
const query = db.query("select 'hello' as message");
console.log(query.get());
- markdown as a first-class citizen: you can parse markdown to html natively without importing some bloated third-party library that hasn't been updated in three years.
performance is not just a benchmark
people talk about benchmarks like they do not matter in the real world. they do. when your test suite runs in 20ms instead of 2 seconds, you actually run your tests. when your package installation takes 1 second instead of 30, you stay in the flow.
the most ridiculous feature is the ffi. if you have a performance-critical task, you can write a tiny c or rust function and call it directly from your javascript. bun even includes a tiny c compiler so you can compile c code at runtime:
import { cc } from "bun:ffi";
export const { symbols } = cc({
source: "./add.c",
symbols: {
add: {
args: ["i32", "i32"],
returns: "i32",
},
},
});
console.log(symbols.add(10, 20)); // calling c from js
stop settling
we have reached a point where the tooling should get out of the way. if you are still manually configuring webpack or waiting for node to transpile your typescript, you are wasting time. if you like this kind of technical deep dive, subscribe to my newsletter by clicking here and provide your active email address