I'm not deep in the webdev / node / Bun ecosystems, I've just been a happy user of Deno for small services for several years. Can someone explain why it sounds like there's such rapid growth of Bun? Is it just being used as a bundler, but not as JS runtime?
Just the permission system alone (though I wish it extended to modules) is so compelling with Deno that I'm perplexed at why someone would transition from node to bun and not node to Deno.
A lot of dependencies and frameworks simply did not work with Deno for a long time. In the beginning it didn't even have the ability to install dependencies from npm. (In hindsight with all the npm supply chain attacks Ryan was probably right about all of these things).
So Bun was a better Node with a lot of very nice quality of life features that just worked and it required much less configuration.
I think the Deno team kind of realized they needed to have compatibility with Node to succeed and that has been their focus for the past couple years.
Edit: And Deno is now more compatible with node than bun.
"Probably"? Are you saying there's a chance he wasn't right?
I really think Ryan deserves a lot more credit than a "probably". He put in a lot of effort to do the right thing and improve the security of the entire ecosystem he created.
Nice to see Deno being maintained. The features listed seem pretty substantial.
and yet Bun's npm compat is much much lower than deno
Seriously, they're both Rust now. They share goals.
In my case, when I start a little Typescript side project, instead of drowning in the sea of npm/yarn/berry/pnpm/bubble/vite/webpack/rollup/rolldown/rollout/swc/esbuild/teatime/etc I can just use one thing. And yes, only some of those are Pokémon moves and not actual tools from the JS/TS ecosystem.
So, I switched to Bun and things have been much smoother!
This is an annoying to do for exactly two platforms: node.js, and deno.
node.js bcs it requires a workaround whenever something networking comes in: fetch doesn't work the same. So you structure you're code around having a node.js workaround. Same story for some other APIs. But you can test if itn works!
Deno is more annoying, you just can't test your package with deno before publishing. Before we released to npm, we installed a tar file and sent those around for testing. Works in node, in vite (node, for browser), works in bun, like a charm. Doesn't work with deno unless you switch to package.json, and you use exactly the subset of the spec that deno supports. You can't "deno install xyz.tar", you have to use npm for that (inserts a single line into package.json), THEN you can use deno to execute. No docs, no hint, just trial & error.
Even more annoyingly, npm & bun both offer 'link': in package repo, call npm/bun link, in the test repo do npm/bun link @yourpackage, and that's it, it's installed. Creates a dyn link to the source's build dir so you can rebuild without packing or sending tars or anything like that, you just build in your package dir and the test project is immediately updated.
Deno doesn't have that. What's worse, they don't tell you they don't have that. Also basically no error messages. It just fails in weird ways. Spent hours trying to do it. Now I just publish without testing for deno and wait for bug reports.
So out of the three: bun just works. That's it. Better than any platform. It just works, and it has a nicer CLI & nicer error messages, and it's faster on startup. It has the web api and the node api (i think) and its own api that's very nice as well, nicer than e.g. node. And e.g. if you run bun link, it tells you exactly what happened: this is what just happened, this is what you have to do to use it elsewhere. Node doesn't have that!
I think deno recognized bun's strategy of using npm dev's backbone as being the better call - that's why they're now slowly introducing node.js features, even though that goes against their original USP.
Node always felt immature compared to stuff like go or java. I still preferred it to go and java. But deno is like node without all the shitty parts. It’s just so simple and productive and has so much good stuff built in. Even building projects with npm packages is easier with deno than with node now.
Bun feels like a faster horse, I guess. I really can’t imagine going back to node/bun on purpose, if I have a choice
Not enough boilerplate and EnterpriseBeanFactorySingleton?
By then bun was already a thing and just ate into its share.
Everything just came together at the right time really quickly and they managed to capitalize on it.
Also at the time Deno had only just started to backtrack on npm-compatibility and it was still in its infancy (I'd say its fully mature today). Bun was ahead of that curve which made it immediately useful.
(It seems too bad ChakraCore is mostly out to pasture and not keeping up with TC-39 and that there's still no good Node-compatible wrapper for SpiderMonkey, but having one for JavaScriptCore is still a breath of fresh air.)
me for example only use nodejs or bun to run a basic sveltekit server, so it can render the html for the first time. all core functionalities are delegated to backend services written in crystal or rust. I don't need some bloated js runtime that hoard 500MB of ram for that purpose (crystal services only take 20+ MB each).
bun promised a lean runtime, every essential functionality is written in zig to increase the speed and memory footprint. and javascriptcore also uses less memory compare to v8. the only thing we expect is for bun to stabilize and can run 24/7 without memory leaking or crashing.
too bad it is a failed promise now.
Bun also includes stuff that you'd need a third party dependency with Deno or Node. Eg: database drivers, S3 client, etc.
Finally, Bun overall has better performance and efficiency compared to Deno.
That said, I'm going back to Node after the recent Bun fiascos with their Rust AI re-write.
Bun has a pragmatic approach from the beginning for being a all-in-one toolset (not just a runtime) and node's replacement. They also has gradual adoption paths such as using bun only as package manager and/or test runner.
Deno since adjusted, but Bun gained a lot of market share in the meantime.
Bundler + used by Claude Code, that’s pretty much it.
And node / bun development is much easier because of many many npm packages.
But Deno's got Node compatibility now, and Node has adopted a lot of the features that make Deno and Bun so usable. So I'm not sure the choice matters so much these days.
Its now 13 years old, not a hard language to have a proper runtime for it and it would just get rid of all the npm stuff.
And for the amount of typescript we now have, it would be worth it to have proper native support.
It means that `<script src="some-url.ts">` works.
Python supports types and is interpreted, right?
C++ was originally a layer on top of C. The first C++ compiler, "cfront" was actually a transpiler to C.
There is nothing preventing TypeScript from becoming "native" in a similar way.
There was a proposal to support TypeScript syntax, but ignore the actual types (this is basically how Python works). That would be kind of nice because you can skip the compilation step completely (less faff for small projects), but I don't think it went anywhere... or if it is it's getting there at a snail's pace:
Node's the stable solution and will be with us forever. You can now use TypeScript with it and, soon enough, you'll be able to build your app to a single executable -- including native deps.
Bun's chaotic but, nonetheless, it's _fast_ and it's taking an interesting approach by including everything in the stdlib. Plus, bought by Anthropic.
Deno had an awesome story with the sandbox and ease of import for third-party dependencies. Sandboxes feel pretty commoditized now and I'm not sure the import mechanism ended up being that much nicer than a `npm add`.
Who thinks this is a positive?!
Whoa, did not know that. That's a killer feature!
This is an interesting development. npm after all is the de-facto ecosystem and leaning into it makes sense.
I'm wondering how Deno would've been received if it supported npm and package.json from day 1.
I would not say npm was the right direction. I actually was a fan of JSR (didn't work on it but all my experience with it was great)
No way it would go through standard build pipelines, or team skills.
https://www.devtoolreviews.com/reviews/bun-vs-node-vs-deno-2...
Similarly, it seems, though they didnt exactly say, that they're running bun with a warm package cache... What about the others? Do they have caches?
As someone who has optimized by reducing/batching heap allocations, 2x seems within the realm of possibility, depending on the exact circumstances.
That being said, iirc, node also has more hooks for things like observability than bun does, which might hurt it here
For those using Node.js, a similar single command is available with https://www.npmjs.com/package/ts-node-pack
Now that Node.js supports importing .ts modules, more repos can use them without a build step or putting any build artifacts in the checkout.
Though I'm also happy that JSR exists as that (mostly) cleaner ecosystem.
They made that intentionally at the beginning:
> Currently there is consensus that Node.js should NOT run TypeScript files inside `node_modules. It is not supported to avoid package maintainers to release TS only package.
The worst of the changes is "lib.node included by default", if I'm writing Deno or web code I absolutely don't want node types included by default. Those types were a pain to deal with even in Node projects, resulting in multiple tsconfigs to avoid those types polluting platform agnostic or web code.
If Deno continues this trajectory then there is less and less reason to use it over Node.
> The worst of the changes is "lib.node included by default", if I'm writing Deno or web code I absolutely don't want node types included by default.
Since a few versions ago, Deno now has some of Node.js APIs included by default (eg. process or Buffer). It's really more of a bug fix to make type-checking work properly.
While it's not ideal, you can still decide which types you want included by default with `compilerOptions.types`. `["deno.ns", "web"]` should give you what you're looking for.
For example, in Deno v2.8 they've changed the return type of setTimeout and setInterval functions from webstandard-compliant 'number' to opinionated 'NodeJS.Timeout'. Which is a short-sighted change trying to reap immediate short-term implementation-centric benefits in the expense of the future. Pains of churn and breaking API changes are welcoming their new bearers...
In my personal opinion, Deno authors are a bit humble. For example, when grateful users offer donations to the project, the authors politely decline them. I understand why, but at the same time it may create unneeded monetary pressures on the project in the long run.
What can work reasonably well is a shut-up-and-take-my-money monthly subscription for users depending on the project long-term success.
It really is such a pleasure. It feels almost like a blend of JS and Go. Fast, flexible, slightly saner package management with more powerful capabilities than other JS/TS alternatives, a better security model, better standard library (so to speak)... And very fast. I love it.
Good work to everyone on the Deno team!
Professionally though, it’s complicated recommending it outside of specific and mostly tightly scoped use-cases. At some point the project just changes direction because of business reasons and you need node.
This software is a beast to build and package. On first compilation, it spent like ~5-6 hours just pulling Rust crates. This time thankfully was significantly reduced once the relevant packages were in cargo caché; only the changed/added ones were picked up.
But the second problem is even more annoying. Building Deno happily consumes about ~16-20 GB of precious disk space on space-constrained SSDs. This is too much.
I think we should go back to more efficient software, both in object code formats (the product) as well as in the build process. Why would a single JS runtime need 20 GB storage to be built? This is wasteful.
If you're using node directly, please stop. At a minimum use Bun.
With agentic work, there is little reason to use anything besides Rust and Typescript in any case. Room to disagree but type safety, memory safety, and a large corpus of work is critical. Agents need difficult errors and baked in patterns they navigate it easily. For UI, Typescript makes the most sense just because of the mass of design examples.
> The release post for v2.8 is not yet published.
> Check GitHub releases page for the latest release status of Deno.
The release is here: https://github.com/denoland/deno/releases/tag/v2.8.0
EDIT: Formatting
Full time for the last three months.
Deno replaced a pnpm monorepo I was using.
And reading the features, I'm impressed! - I spot many commands & features that map to my workflow.
Well done Deno team.