require(esm) in Node.js: implementer's tales

In earlier posts, I wrote about reviving require(esm) and its iteration process. The idea seems straightforward once you grasp the ESM semantics, but battle‑testing revealed interop edge cases rooted in existing ecosystem workarounds. Along the way, several escape hatches were devised to address them.

Read More

require(esm) in Node.js: from experiment to stability

More than a year ago, I set out to revive require(esm) in Node.js and landed an experimental implementation. After a lot of iteration and battle-testing, require(esm) is now unflagged across all supported Node.js LTS release lines (v20.19.0+, v22.12.0+) and has just been marked as stable. This post reflects on how it progressed from experiment to stability. In the next post, I’ll cover implementation details and the interop hatches devised for a smooth ESM transition.

Read More

Building Node.js on Windows with clang-cl

Recently Node.js started to support building with clang-cl on Windows. I happened to have the chance to try it out this week and while it still needs some fixups in my case, it’s mostly working very well now. Here are some notes about this.

Read More

Executable loading and startup performance on macOS

Recently, I fixed a macOS-specific startup performance regression in Node.js after an extensive investigation. Along the way, I learned a lot about tools for macOS and Node.js compilation workflows that don’t seem to be particularly well documented on the Internet, so this is my attempt to put more useful information out there in the hope that it can help someone else doing something similar.

Read More

Reproducible Node.js built-in snapshots, part 3 - fixing V8 startup snapshot

In the previous posts we looked into how the Node.js executable was made a bit more reproducible after the Node.js snapshot data and the V8 code cache were made reproducible, and did a bit of anatomy on the unreproducible V8 snapshot blobs. In this post let’s see how we made the V8 snapshot reproducible and finally made the Node.js executable reproducible again on Linux.

Read More

Reproducible Node.js built-in snapshots, part 2 - V8 code cache and snapshot blobs

In the previous post, we covered how the Node.js built-in snapshot is generated and embedded into the executable, and how I fixed the Node.js bits of the snapshot to make the executable more reproducible. Now we get to the harder part - the binary V8 startup snapshot blob and the code cache were still not reproducible after the aforementioned fix, so it’s time to dig into V8.

Read More

Reproducible Node.js built-in snapshots, part 1 - Overview and Node.js fixes

In a recent effort to make the Node.js builds reproducible again (at least on Linux), a big remaining piece was the built-in snapshot. I wrote some notes about the journey of making the Node.js built-in startup snapshot reproducible again, hopefully it can help someone else who were trying to do the same thing (or my future self since I have a bad memory) .

Read More

Things I learned from organizing a hybrid unconference

Recently, I co-organized a hybrid unconference - the Node.js collaboration summit for 2024 H1. This was the first time I participated in organizing an event like this, and I learned a lot from the experience, so I decided to write this blog post, hoping that it may help others looking into organizing a hybrid unconference.

Read More

require(esm) in Node.js

Recently I landed experimental support for require()-ing synchronous ES modules in Node.js, a feature that has been long overdue. In the pull request, I commented with my understanding about why it did not happen sooner before this pull request in 2024. This post expands on that comment a bit more.

Read More

Memory leak regression testing with V8/Node.js, part 3 - heap iteration-based testing

In the previous blog post, I described the heap snapshot trick as an “abuse” of the heap snapshot API, because heap snapshots are not designed to interact with the finalizers run in the heap. But the concept of using heap snapshots to identify/disprove leak itself is not an abuse - that’s exactly what they are designed for. Well then, can we use heap snapshots, or a simpler version of it, to test gainst memory leaks?

Read More