If you like Node.js but not its package manager npm, or you want a more secure JavaScript runtime environment than Node.js, you might find the new open source project Deno of interest (the word Deno is an anagram of Node). On the other hand, if you’re using Node.js in production, there’s nothing to see here, move along – Deno is still “very much under development.”
Deno is a program for running JavaScript and TypeScript code outside of a browser. It’s the most recent effort spearheaded by Ryan Dahl, who founded the Node.js project in 2009, and it is an attempt to reimagine Node.js in light of the advances in JavaScript since 2009, including the TypeScript compiler. Like Node.js, Deno is essentially a shell around the Google V8 JavaScript engine, although unlike Node.js it includes the TypeScript compiler in its executable image.
Deno and advanced JavaScript
In 2009, JavaScript lacked several features that would have been useful for Node.js, according to Dahl. A few of these have been added to JavaScript over the years as part of the ECMAScript (ES) standard, and TypeScript has addressed a few more.
JavaScript has had events and callbacks essentially forever, but they can lead to rather complicated code, especially when you want to chain asynchronous actions. Promises make the syntax a bit more readable. A promise
is a returned object representing the eventual completion or failure of an asynchronous operation, to which you can attach callbacks, as opposed to passing callbacks into a function. Declaring a function async
further simplifies the syntax, allowing you to use await
within the function to pause in a non-blocking way until the promise settles.
When Node.js was created, the de facto standard for JavaScript modules was CommonJS, which is what npm supports. Since then the ECMAScript committee officially blessed a different standard, ES Modules, which is what jspm supports. Deno supports ES Modules.
Typed arrays are an ES6 API for handling binary data, something Node.js could have used; the lack of binary data support led to some Node.js design issues. Deno uses typed arrays when it needs to manipulate raw binary data. Node.js now supports typed arrays for user code.
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript (ES3 or higher; it’s configurable). TypeScript adds optional types, classes, and modules to JavaScript, and supports tools for large-scale JavaScript applications. (Anders Hejlsberg calls it “JavaScript that scales.”) As mentioned earlier, Deno contains an image of the TypeScript compiler as part of its runtime. If you pass Deno a TypeScript file it will first compile it to JavaScript and then pass that to the V8 engine.
Node.js design shortcomings
According to Dahl, who after all did design both Node.js and Deno, Node.js suffers from three major design issues:
- a poorly designed module system, with centralized distribution;
- lots of legacy APIs that must be supported;
- and a lack of security.
Deno fixes all three problems.
Deno secure execution
The way Deno improves security over Node.js is simple: By default, Deno won’t let a program access disk, network, subprocesses, or environmental variables. When you need to allow any of these, you can opt in with a command line flag, which can be as granular as you like, for example --allow-read=/tmp
or --allow-net=google.com
. Another security improvement in Deno is that it always dies on uncaught errors, unlike Node.js, which will allow execution to proceed after an uncaught error, with results that may not be predictable.
Deno modules
In Node.js, you load CommonJS modules using the require
keyword and they all, standard and third-party alike, implicitly come from npmjs.com. In Deno, you load ES modules using the import
keyword and explicitly state the URL. For example:
import * as log from "https://deno.land/std/log/mod.ts";
Deno modules can be hosted anywhere – there is no centralized repository for third-party modules. In addition, modules are always cached and compiled locally, and aren’t updated unless you explicitly ask for a refresh. Therefore, you should be able to run Deno programs that are already on your laptop, as long as all the imports have been resolved once, even if you are on an airplane with no connectivity.
Deno does have a centralized collection of standard modules that do not have external dependencies and are reviewed by the Deno core team; it lives on the deno.land server. The deno_std module collection is a loose port of Go’s standard library.
There is a little history behind that choice of model for the library. Dahl wrote his prototype of Deno primarily in the Go language, but discovered potential conflicts between the garbage collectors in Go and V8. He and his collaborators then rewrote Deno proper with V8, Rust, and the Rust asynchronous I/O package Tokio. They implemented the Deno standard library in TypeScript.
At this point, Deno is a reasonable and fun environment to use for building small private scripting projects in TypeScript. According to Dahl, Deno will never really affect the success of Node.js. Nevertheless, once Deno reaches version 1.0 it may well become a viable choice for building larger projects.