My thoughts on Bun and other Adventures
Bun 1.0 release, Node.js performance, and released videos on OpenMeter and EventEmitter anti-pattern.
Hi Folks!
As I write this, I'm on a plane to London, where I will spend the entire week working with my co-founder, Luca Maraschi. Since I last wrote, there has been quite a bit of news.
Bun 1.0
Bun hit the 1.0 release, and I'm both excited and disappointed. I really like what Jarred Sumner is building with Bun, but I'm a bit frustrated by their compatibility claim with Node.js. In my experience, it's not a drop-in replacement, and many inner details differ. This results in many random issues over my repos asking for fixes for Bun incompatibilities while people try it out. I would have preferred if they waited for calling a 1.0 to reach greater compatibility with the ecosystem.
Why is Bun faster than Node.js?
A few reasons:
- Node.js has no budget, and a tiny team maintains npm. Most investments are in adding capabilities or things more secure, not making things faster. Making things faster does not make anyone more money; it’s a bit of a tragedy of the commons. Moreover, the cloud providers (the real money-makers these days) have no interest in improving the performance of anything, as it would mean less revenue for them.
- Bun did not care about backward compatibility with a significant portion of the npm ecosystem. They made things fast and are working to preserve backward compatibility as an after-fact: this is how you approach building fast software. Conversely, Node.js processes are built around protecting the ecosystem instead. We know how to make Node.js faster, but doing so will create a lot of friction for the end users.
- I believe in open standards and open governance. Runtimes and infrastructure are better with it (see the terraform fiasco). Having open governance means a broader decision-making process, which makes everyone heard, but it also requires more time to make decisions.
Bun does not currently support Pino and Fastify
As I'm writing this, Bun does not support Fastify or Pino. Both are high-impact modules, with pino being as popular as Next.js. The Bun team is actively looking into adding the missing APIs and behaviors, and I expect them to catch up in the coming months. Given how many are asking for support, a variation of the following message ended up in my GitHub saved reply:
Ultimately, Bun does not implement all Node.js APIs. It's not a clean drop-in replacement for Node.js (despite their claims). Please refer to the Bun Discord or Issue Tracker for such questions.
If any of my repositories do not run well on Bun, please open a bug on Bun. This approach is also what Jarred asked everybody to follow.
bun install
speed comes at a cost
One of the most impressive things about Bun is the performance of bun install
. However, it comes with a considerable cost in developer experience.
npm
, pnpm
and yarn
check if a new version is available and fetch it from the registry by default. Instead, bun
would pick a local version first.
In fact, pnpm --prefer-offline
flag has roughly the same behavior of bun install
and it yields performance in the same ballpark: on my system 750ms vs 150ms (see also this tweet from Evan You). While this difference matters, the two numbers are comparable, and hopefully, the gap will be reduced.
What would be interesting is how the end users would appreciate this difference in behavior. Would you use the latest and the greatest, or what you have installed locally, knowing you might lose on bug or security fixes?
I was also very impressed by the clever use of copy-on-write on Mac OS X, making it almost instantaneous with a hot cache. This is partially due to clonefile
, which tells the operating system to copy the file only when modified for the first time, saving precious seconds. I hope all the other JavaScript package managers copy this technique.
What's next for Node.js?
For a few years, Node.js invested very little in improving the runtime performance. Last year, Yagiz Nizipli kicked off the Performance Team, and it's now a strategic initiative. This has led to quite a few significant Performance improvements that are described by Rafael Gonzaga) in the State of Node.js Performance 2023. Node.js is getting faster at each release, without massive breaking changes.
Would you like for Node.js to become faster? Join the performance team and contribute... alternatively, find a way to fund the development of Node.js.
Videos
Have you ever wondered how to implement usage metering for your SaaS? In this video, I pair up with Peter Marton to find out what OpenMeter is, how to use it, and how it enables tracking how much a user has used a specific feature. We will also check if the new Platformatic client would generate a good client for OpenMeter... and we have found a few bugs!
I also recorded a video explaining why using EventEmitter with an async function is an anti-pattern. Are you using this pattern? Stop now!
I've also been busy building Platformatic in public: we are adding automated tests to the code created by the create-platformatic
generator, so all the harness for testing is already set up.
Follow along with the development at https://github.com/platformatic/platformatic/pull/1323.
Releases
- @fastify/mongodb v8.0.0 updates to
mongodb@6
driver and drops Node.js v14. - @fastify/static v6.11.0 add URL type.
- @fastify/leveldb v5.1.0 updates dependencies and TS nodenext compatibility.
- @fastify/secure-session v7.0.0 updates
@fastify/cookie
to v9; v7.1.0 adds a.touch()
method to refresh the session. - @fastify/throttle v1.0.0 new plugin throttling a request's download speed.
- @fastify/restartable v2.1.1 fixes a type.
- @fastify/oauth2 v7.3.0 allows default cookie options to be overriden; adds gitlab provider.
- @fastify/jwt v7.2.1 adds FastifyJwtNamespace type helper.
- @fastify/oauth2 v7.4.0 implements yandex configuration in prese; Add default user-agent + enable custom one; implement revoke token and revoke all token.
- pino-http v8.5.0 loosening up the IncomingMessage and ServerResponse typings.
- pino-abstract-transport v1.1.0 fix CJS default exports in types.
- mercurius-upload v7.0.0 switches from graphql-upload to graphql-upload-minimal, drop Node.js v14.x and v16.x.
- @fastify/swagger v8.10.0 adds endpoint-specific transforms.
- pino-elasticsearch v6.7.0 adds
opts.rejectUnauthorized
for SSL option. - @fastify/session v10.5.0 fixes an issue where the session is not saved when
request.session.cookie.expires
isnull
. - pino v8.5.1 increases test stability for Node.js CITGM.
- fastify v4.23.0 adds a new
onListen
hook! - fluent-json-schema v4.1.2 removes a duplicate type definition.
I'm trying out htmx!
fastify-html v0.1.0 is a new module I plan to use to explore htmx. I'm planning a stream on this in the coming weeks. Would you join?
Links
-
How much drama can happen if a major technical influencer drops TypeScript? It sparked a massive flame war between TypeScript lovers and haters.
-
Announcing native npm support on Deno Deploy - Amazing news as Deno can know run Fastify at the edge!
-
How we built Pingora, the proxy that connects Cloudflare to the Internet - read this amazing engineering story on how CloudFlare replace NGINX.
-
I've found this online book quite interesting - How Query Engines Work; maybe I will implement one day!
-
When URL parsers disagree (CVE-2023-38633) - Canva Engineering Blog - who said that parsing a URL was easy?