Why I still reach for Rust
I write a lot of TypeScript for a living. I like TypeScript. But when a problem absolutely has to be correct and fast — a parser, a tunnel, a library other people will build on — I keep coming back to Rust. This is my attempt to explain why, without turning it into a language war.
The compiler is a collaborator, not a gate
The common complaint about Rust is that the borrow checker fights you. For the first month, it does. After that, something flips: you stop experiencing it as a gate and start experiencing it as a collaborator that has already read your code more carefully than you have.
When I built Multer, an async parser for
multipart/form-data, the entire class of “use-after-free while streaming a
half-parsed upload” bugs simply could not be written. Not “was caught in review” —
could not be written. For code in the hot path of file uploads, that guarantee
is worth more than any amount of test coverage.
Pick the tool by how much the mistake costs
Here’s the rough heuristic I actually use:
- JavaScript / TypeScript — when iteration speed and ecosystem reach matter most, and a bug means a quick redeploy. Most product UI lives here.
- Go — when I want concurrency and a single static binary without much ceremony. Great for services and CLI tools.
- Rust — when correctness and performance are the product, and a bug is expensive or impossible to take back. Libraries, parsers, anything on a hot path.
It’s not about one language being “better.” It’s about matching the cost of a mistake to the strictness of the tool.
The ecosystem grew up
The Rust I started with had gaps everywhere. Today the async story is solid, hyper and tokio are battle-tested, and the crate ecosystem covers most of what you’d reach for. The libraries I maintain exist because that foundation got good enough to build on.
Rust isn’t my default — TypeScript still is, because most work doesn’t need
Rust’s guarantees. But for the small set of problems that do, nothing else makes
me feel as confident shipping. And confidence at the point of git push is, in
the end, what I’m optimizing for.