The problems of Node, as Dahl noted during the Node js announcement, come from how it manages the codes. Here are the major mistakes of Node js that have marred its use by developers and become serious threats to its future.
Not Sticking With Promises
Though Dahl included promises to Node js when he created it in 2009, he removed them early in 2010. If he had stuck to the promises, their unified usage would have hastened the delivery of the ultimate standardization and async/await. Because of this, Dalhl regretted in the Node js announcement that most of the Node js async APIs are out of date and unreliable.
In Node js, there is less focus on security. For example, if you use the Node program, it is able to access all your system calls including access to the network and writing to the disk. This is not good for Node js developers or users. For example, the linter should not get total access to the computer and network.
The Build System (GYP)
The continued use of GYP is one of the largest shortcomings of the node core. GYP is used for writing modules that link them to C library and link it to Node. GYP comes with unnecessarily complex wrappers around it and Node js developers find using it an awful experience. Instead of directing developers to write C++ bindings to V8, the better option would have been the core foreign function interface (FFI). Like Dahl pointed in the Node js announcement, even chrome dropped GYP leaving Node as the sole GYP user.
Though Isaac, in NPM, created the package.json, Dahl sanctioned it by allowing Node to inspect package.json. The biggest mistake as Dahl noted in the Node js announcement, however, was including NPM in the Node distribution. This means that it became the defector standard. But, it has many types of unnecessary information requirements (noise) such as description, license, and repository when js developers simply need to link to a library.
node_modules greatly complicates the Node module resolution algorithm. It is vendored-by-default with good intentions for developers but a common $NODE_PATH would work effectively. In the Node js announcement, Dahl regretted that the node_modules also greatly deviates from browser semantics.
Require Module without Extension.js
Node does not require developers to include extensions in the require module. This is needlessly explicit because the module loaded has to keep querying the file system at different locations simply trying to figure what the Node js developers anticipated. It also deviates from how the browser operates.
This was needlessly introduced from the beginning based on the view that it would be awesome. However, it unnecessarily complicates the module loading system for Node js developers.
Deno is a secure typescript run-time on V8. It is written in GO though it is being redone in Rust. The core of Deno could look similar to Node.js but it has a greater focus on security, cornerstone on details, and lightweight nature that makes it intriguing. Dahl was especially regretful about Node.js security and wanted to ensure that the same will not replicate in Deno. Note that Deno is not explicitly compatible with Node.js.
Deno, unlike Node.js, takes full advantage of JS because it is a secure sandbox. The underlying principle, as Dahl explains, is that scripts should by default run without any write access to your system file. It is the user who should opt in to access through flags and, therefore, making it possible for scripts to run untrusted utilities. A good example is linter.
Another notable thing about Deno is that it does not allow any arbitrary native functions getting bound into the V8. Instead, all system calls are done through message passing. Because native functions are only two; send and receive, Deno becomes simpler and easier to audit. See the demonstration of Deno below:
The other main goal of Deno is to simplify the module system. The imports provide remote URLs and extensions that have to be fetched and cached indefinitely with the first load. It also does away with the file manager and shifts to NPM package manager.
The Final Take
Dahl shift from Node.js to Deno is a broad step demonstrating that no matter how good any application is today, it needs to be improved progressively to cater to the changing needs. Besides, Dahl demonstrates that developers should learn to appreciate current developments such as TypeScript and leverage them to get better products.
Though Deno is more comprehensive and thought about, only time will tell about its success.