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.
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: