Node.js rival Deno adds stable npm compatibility in effort to bridge module system divide

The Deno team has released version 1.28 which “stabilizes npm compatibility,” according to a post today.

This is a key feature since the npm (Node Package Manager) registry is hugely popular. When Microsoft’s GitHub acquired the npm registry it claimed 1.3 million packages and 125 billion requests per month. Today, npm has over 2 million packages and approaching 200 billion downloads per month.

The way npm packages works with Deno is described here. There are two approaches, of which the preferred technique is npm specifiers. In this case, npm modules are imported directly in Deno code. No node_modules directory is required. Node.js itself uses a node_modules directory in the application source. The team confesses though that “even though this feature was stabilized for use with deno run and some other sub commands in Deno 1.28, it is still under development and doesn’t work in some scenarios (ex. with deno bundle).”

The other, older approach is to use a CDN (Content Delivery Network) which wraps or modifies npm packages to work with Deno. The primary issue is that code written for Node.js most often uses the CommonJS module system, whereas Deno uses the EcmaScript module (ESM) system. ESM has native browser support and is therefore preferable, but the widespread use of CommonJS, which was available before ESM was standardised, makes it hard to avoid.

Deno’s npm support comes via an addition to the Deno standard library, std/node, which provides a compatibility layer for Node’s built-in modules and a mechanism for loading CommonJS modules.

The Deno team is defensive about its npm support. “Deno maintains that modern JavaScript should be built with ES Modules and web standard APIs. This release does not change that,” states the post on the matter. As so often though, compatibility matters more than purity. “Deno is taking npm a step forward by allowing you to access your favorite modules in a modern, secure programming environment,” the post adds.

There may be some pressure from the new rival Bun, still in preview, which has made Node.js compatibility a goal from the start as well as showing better performance than either Deno or Node.js. DevClass asked Netlify CEO Matt Biilmann about Bun versus Deno – bearing in mind that Netlify adopted Deno for its Edge functions earlier this year.

“Bun falls in the same category [as Deno] and is super interesting,” he told us. “The performance story there, I would have some caveats. It’s always easier to be faster when you’re not doing all the things,” referencing the fact that Bun is not yet feature-complete.

“One of the big questions will be around Node.js compatibility versus Deno’s attempt to refocus on the Web API,” said Biilmann. The dilemma is that “there’s so much investment in the whole Node.js ecosystem and all the libraries and tools around it … there’s a lot of inertia there.” That said, “it’s also true that you get a simpler mental model, the closer the browser environment and the server environment get to each other … it’s another reason why we went with Deno for our Edge runtimes. But even then, they have needed to introduce an adapter layer between the npm ecosystem and the Deno ecosystem, just from market demand.”

This then is that adapter, which in theory may give Deno developers the best of both worlds. Then again, the Node.js team is also working on this in the opposite direction, adding ESM compatibility, and remains dominant in overall usage.