Deno - The new JavaScript runtime that's fixing Node

Posted Feb 11, 2021

Anthony Gore
Author
Oleg Krivtsov
Research


Node.js is the most popular web server for JavaScript. Now more than a decade old, the JavaScript language and ecosystem has evolved dramatically since its creation. Is it time for something new?

What is Deno? #

Ryan Dahl, the creator of Node, believes his creation has room for improvement. He now has a vision for a next-generation of Node which will feature:

  • Simple and clean installation
  • A set of convenient built-in tools
  • Enhanced security
  • Parity with web standards like ES Modules

This new project is called Deno (notice the name De-no is No-de reverted) and it reached a 1.0 release in May 2020.

Although not ready for production apps, it's quickly taking shape and is proving to be a clear improvement for a JavaScript developer's life.

In this article, we'll dive deeper into some of Deno's improvements over Node.

Easy installation #

To use Node, you'll need to install Node as well as Node Package Manager (NPM).

In contrast, Deno ships as a single executable with no dependencies. In fact, you can install it and set it up in just one line:

curl -fsSL https://deno.land/x/install/install.sh | sh

Creating a Deno project #

Unlike Node, we don't need to start a project with npm init. We can simply create a JavaScript script file:

touch server.js

In this script, let's use Deno's http module:

// server.js

import { serve } from "https://deno.land/std@0.85.0/http/server.ts";

This one line reveals several more interesting things about how Deno works:

  • It uses ES modules instead of CommonJS
  • It uses a URL to import, not NPM
  • It features a standard module library
  • It comes with out-of-the-box TypeScript support.

Let's discuss all of these aspects now.

Standard module library #

Deno provides a set of standard modules for common functionality that is updated every time the Deno runtime is updated.

The complete list of standard modules can be found here, but here are a few popular ones:

  • datetime for parsing date strings
  • fmt prints formatted output
  • http provides an HTTP server implementation
  • log provides logging
  • path for manipulating file paths

Parity with web standards #

Most Node packages use the CommonJS module format. These have the familiar require syntax e.g.

const http = require("http");

While this format works well enough, it's not part of the ECMAScript standard that JavaScript is based off since at the time of Node's release, there was no standard!

In recent times, ECMAScript has finally settled on ES Modules as a standard. Unlike CommonJS, these are supported in any environment JavaScript can run in, including browsers.

You'll probably be familiar with the ES Modules syntax which uses import and export statements.

The advantage of using ES Modules is that Deno apps will allow isomorphic code that can be run in multiple environments. Node apps will be held back by the need to ongoingly support CommonJS.

No more node_modules, NPM, or package.json #

The next unfamiliar thing you'll notice about this Deno script is that the module import uses a URL rather than a local file path:

// server.js

import { serve } from "https://deno.land/std@0.85.0/http/server.ts";

This is distinct from Node.js and almost every other JavaScript-based project which rely on node_modules and package.json.

For all of its advantages, NPM has some serious downsides, especially it's security flaws and fragile system of centralization (remember when left-pad broke the internet?)

Deno decentralized way of resolving dependencies by URL makes it possible to store modules on GitHub or in any other place accessible on the web.

Package versions can be set in the URL or in a central deps.ts file (which is much simpler than the bloated package.json file).

When a Deno app runs for the first time, these dependencies are downloaded and cached so that it can run later (offline if needed).

Looking for modules compatible with Deno? See https://deno.land/x.

TypeScript and other features out-of-the-box #

The next improvement is Deno is that it has built-in TypeScript support.

For example:

touch server.ts

Let's expand on the script we made before so it launches the file server:

// server.ts

import { serve } from "https://deno.land/std@0.85.0/http/server.ts";

function launch (port: number): void {
serve({ port });
}

launch(8080);

In addition to TypeScript, Deno offers several other built-in features including a linter, dependency inspector, and test framework.

These can all be run from the CLI:

  • deno fmt server.js will format your script to make it pretty
  • deno lint --unstable server.js will lint the script
  • deno info server.js will inspect the dependency tree of the code
  • deno test server_test.js will run tests

Increased security #

Node apps can read and write to any place on your file system, as well as access the network and environment data.

This convenience has lead to security holes and vulnerabilities. For example, some malicious NPM packages have been known to steal sensitive information right off a user's system.

Deno provides an enhanced security model similar to the SELinux mechanism in the Linux core or to the Chrome browser's security model.

By default, it won't give an app access to the network or the file system. Instead, a prompt will appear and the user will have to explicitly grant the app permission.

For example, to run the script we just made with network access we'd need to use the --allow-net flag:

deno run --allow-net example.ts

Promises-based APIs #

The final feature to mention is that Deno APIs use Promises by default. This is contrasted to Node which uses callbacks. The main reason is that, again, Node was created at a time before Promises were standard in the JavaScript language.

One drawback is that this makes the Deno API incompatible with Node.js.

Note: although Deno does not support NPM modules directly, it provides a Node compatibility library, which allows you to use some NPM modules.

A note about performance #

Deno is built with the Rust programming language which allows it to be efficient and fast.

Although performance improvement is not the main goal of Deno, there is this research
by John Guo which shows that Deno outperforms Node in a high-traffic network.

It's not unreasonable to expect that Deno code may be further optimized and show better performance with time.

Criticism of Deno #

Not everyone loves Deno. This article by blogger Mehul Mohan criticizes Deno for its monolithic approach and the new security model.

He argues that lean systems are easier to work with and the security model of Deno is not typical for backend runtime systems.

Also, the incompatibility with Node.js APIs makes the migration to Deno time- and effort-consuming.

Wrap up #

The key idea of Deno is to provide a more convenient, secure, and modern alternative to Node.js, and it appears to have achieved that.

Deno does not aim to replace Node.js, but it may still do so unintentionally! Only time will tell.

Let us know in the comments if you've tried Deno and what you like most about it.

You might also like...


Did you enjoy this review? To help us bring you more just like it, consider sponsoring Dev Reviews on Patreon!

Become a Patron