Skip to main content

Node's Complexity Problem

Though Node is ubiquitous on the web today, it was never intended to be the runtime for the web. But it did tap into a growing appetite from web developers to use JavaScript for everything. In Node’s (and npm’s) ever expanding scope to service these wide ranging use cases, building a simple web app became burdened with flaky complex build steps, setting up tooling, managing dependency discrepancies, and using shims and polyfills to bridge the gap between using web standards APIs.

Ryan Dahl’s goes over his regrets while building Node that led to its unnecessarily complex state today.

Too much config

Starting a new project in Node.js requires several steps before you can actually start programming. Setup TypeScript. Setup your testing framework. Setup a formatter. A linter. A type checker. Set up your bundler. Add the right plugins. And after selecting your tools, tweak all their config files so they work well together. Some Next.js projects have over 30 config files in them.

Programming should be just that — programming — and not configuring tools before you write a single line of code.

Divergence from web standards and browser JavaScript

Since Node.js was created as an event-driven, asynchronous I/O JavaScript runtime, web standards and interoperability were not the main focus. As a result, Node.js invented its own set of APIs (e.g. fs, path, to name a few) and its flavor of JavaScript diverged from that used in the modern browsers. This led to further complexities when using Node.js to build for the web, as you’re now required to add bundlers, source mappers, transpilers, shims, and more into your workflow.

Module loading and resolution

Node’s node_modules folder and its “vendor-by-default” strategy massively complicates the module resolution algorithm. Sometimes different packages require different versions of other packages, leading to complex dependency trees with circular and peer dependencies requiring a different version of the same dependency. This results in time spent auditing dependencies as well as long build times.

Node modules are the known heaviest things in the universe

The scope of npm’s package.json expanded over time and today includes too much boilerplate. When creating a JavaScript module, we now need to include frivolous details like LICENSE information. If you want to write and share a single file JavaScript program, you shouldn’t need to fill out a lengthy questionnaire.

Deno: a clean start, built for the web

We recognized these deaths-by-a-thousand-paper-cuts with Node.js and re-imagined from the ground up what a modern, productive, and simple approach to building web and cloud software could be.

Deno is a single, simple system — not a myriad of disparate tools like npm, node-gyp, gulp, grunt, jest, etc. — with the development tools you need without any config needed so you can jump right into coding.

Learn more about Deno: