Colin here, creator of Nub. I’ve had the general shape of this in mind for years. Nub runs your code with stock `node`, augmented with a `--require` preload hook[0] that adds a transpiler (oxc-powered, packaged as a Node-API add-on), registers a module resolution hook[1], and injects polyfills as needed for APIs like `Worker`, `Temporal`, etc. All purely additive, your code ultimately runs using Node’s actual engine & stdlib implementations.

[0] https://nodejs.org/api/cli.html#-require-module

[1] https://nodejs.org/api/module.html#moduleregisterhooksoption...

I actually really like this! Great choices all around.

I’m surprised to see this using a `--require` hook (rather than `--import`). Maybe something’s changed significantly since I was looking into building some similar functionality… but it makes me wonder about nuances in nub’s ESM support.

(When I was investigating this it was very early in Node’s `--import` story, but there were several edge cases with the more common ESM-to-CJS approaches that I wanted to address. Most were probably exceedingly niche concerns, but I’d expect top-level await to affect a meaningful subset of users.)

We use this to register our preload purely for performance reasons. In this and many other cases CommonJS is still faster than ESM. Using --require is about 0.5ms overhead vs 4.6ms for --import (on my M1 Macbook Pro).

Relatedly Node.js recently (2025) introduced a synchronous version of its resolver hook registration API (`module.registerHooks()`) specifically to improve performance over the old async `module.register()` API. It was a big unblocker for Nub. For the interested, the async API added 19ms fixed registration overhead + about 130us additional overhead per import.

Which flag Nub uses here doesn't impact userland at all, TLA is supported wherever it's supported by Node.js itself.

Thanks! From what you say here and what I see in the docs, it looks like everything is much simpler and more robust than when I was exploring the space. I’m happy to see that, and thrilled it’s mature enough now to support use cases like nub.

I saw this on twitter and loved it, such a good move on your part Colin. Hope the project picks up tons of steam!