Technology waves tend to follow the same pattern: a tool built to solve a very specific, very hard problem earns a deserved reputation, and then it starts showing up in contexts that don't share any of the characteristics that made it the right choice in the first place. Right now that tool is Rust, and it keeps appearing in internal dashboards and CRUD applications that serve a few hundred users.
That's the wrong call. Not because Rust is bad - it's extraordinary, and I mean that without irony, because the problems it was designed to solve are genuinely hard and it solves them in ways that no other mainstream language does. But an extraordinary tool used in the wrong context produces ordinary outcomes, and sometimes quietly catastrophic ones, because the people who picked it spend their time fighting the tool rather than building the product. For ordinary web application work - the kind that most of us do most of the time - Bun and TypeScript are the better bet, and the reasons for that compound over the life of the project in ways that aren't obvious on the first day but become very obvious on the five-hundredth.
One Language, Everywhere
With Bun and TypeScript you write one language across the whole stack: server logic, database queries, the API layer, frontend components, build scripts, test runners, CI pipelines. You get strong typing, modern tooling, and the ability to share types and validation logic between the server and the client without a translation layer in between.
Rust on the backend means your frontend engineers cannot read your server code. That gap is invisible on the org chart and very visible the moment something breaks at the boundary between them, when the person who could fix the frontend problem cannot follow the logic into the backend without context they don't have.
The Knowledge Base Is Enormous - and That Matters
When someone on your team hits a confusing async boundary in TypeScript, an answer is minutes away: a thread, a documentation page, a reproducible example. The equivalent wall in Rust - lifetime errors, pin projections, async trait objects - sends them into language RFCs and forum threads that assume expertise they don't yet have. The language isn't harder for the sake of being harder; it's solving problems your CRUD app doesn't have, and your team pays the learning cost anyway, every time someone new joins or someone senior leaves.
There is also something worth saying about maintenance over time. The developer who wrote the clever Rust service may not be there in two years. The developer who inherits it may not know the language. TypeScript code written three years ago by someone who has since left is still, overwhelmingly, readable by whoever picks it up today - and that readability, boring as it sounds, is a form of engineering value that doesn't show up in benchmarks.
Bun Eliminates the Build Step
You run TypeScript directly. No compile step, no bundler config to debug, no fifteen-minute cold starts in CI while the build tool decides what it needs to do. You write a .ts file, run it with bun run, and it works. On a project that several developers will touch over several years, zero build tooling is not a small convenience - it is a maintenance advantage that keeps paying out long after launch, because the thing you didn't add is the thing you will never have to upgrade, migrate, or explain.
A Word on LLMs
LLMs are very good at generating TypeScript and JavaScript. The training data is vast, the patterns are well established, and a prompt for a Bun HTTP handler usually comes back as coherent, idiomatic, immediately runnable code - code you can read, adjust, and own without spending an afternoon understanding what the generator was thinking.
The catch is that generated code still has to be read, understood, and owned by whoever ships it, and that means knowing the language it's written in well enough to catch what it got wrong. Excellent LLM-generated Rust is still a liability when nobody on the team can confidently follow its logic under pressure. TypeScript keeps the developer in the seat: the output is readable, fast to correct, and fast to reason about at two in the morning, which is exactly when you most need to be able to reason about it.
The Takeaway
Cognitive overhead kills more projects than slow runtimes do. For us, that means one language the whole team can read, on a stack with decades of accumulated knowledge and the largest developer community in the world behind it - one language from database query to browser component, no build step, shared types end to end, and LLM output the team can actually audit and own.
In the long run, the boring choice wins. It wins because the team can move, because the next person can understand it, and because "boring" in technology usually means "tested by so many people that the surprises are mostly gone." That is not a small thing.