Blog

From Node to Deno: a test drive of the new kid in town

21 Dec, 2021
Xebia Background Header Wave

If you like Node and Typescript you should be curious to checkout Deno, the new baby from Node’s creator Ryan Dahl.

Deno was born from Ryan’s regrets on some design choices made in Node, especially around security, module management and APIs.
Deno addresses those regrets with a brand new Typescript runtime built on Rust and V8 that has several goals:

  • Be secure by default
  • Embrace standard Web APIs
  • Simplify dependencies management

and many more.

Does it succeed in accomplishing them?
That’s exactly what we set out to find during our last Innovation Day at Xebia.
Here are our first impressions after playing with it for a few hours.

Easy landing

The first thing we noticed about Deno was how easy it is to get started.
It is a breeze to install with a one liner from the command line:

#Shell (Mac, Linux):
curl - fsSL https://deno.land/x/install/install.sh | sh

#PowerShell (Windows):
iwr https://deno.land/x/install/install.ps1 -useb | iex

#Homebrew (Mac):
brew install deno

Also, it is a single executable that provides many development tools out of the box instead of having to rely on third party solutions: it has a built-in linter, formatter, test runner, bundler, a REPL console and more.

We had a fully working setup in just a couple of minutes spent installing a plugin for our favourite IDE. There’s support for Visual Code, Atom, IntelliJ, Sublime, Vim, and many others.
Given the similarity with Node and Typescript we were able to get up and running incredibly fast.

Main Features

Running a program is done with the deno run command (it also supports a –-watch mode).
You can run a remote script:

deno run https://deno.land/std/examples/welcome.ts

Or run a locally defined one:

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

console.log("https://localhost:8000/");
serve(() => new Response("Hello World\n"), { addr: ":8000" });

The script above allows us to already see several interesting bits:

  • There’s no more package.json or similar: dependencies are imported directly in the file with a URL. You can grab modules from Github, remote servers or CDNs. Deno takes care of caching them locally and reusing them.
    It is a simple and effective choice, but it does put the burden of keeping the dependencies clean and manageable on the developer (we really suggest using import maps)
  • If you run the script you will get an error because it tries to access the network.
    Contrary to Node, for security reasons Deno requires explicit permission to access resources like the file system or the network. In this example it needs the –allow-net flag to work.
    The permission model is simple yet flexible, allowing for example to limit file system access to a specific folder in read only mode, or whitelist network access only to a specific host or port.

      Deno takes care of downloading (and caching) the dependencies, bundling your application and running it. No other tools or configs are needed. Optionally you can even compile your program into a native executable!

      Web APIs

      Let’s look at another example:

      const jsonResponse = await fetch("https://api.github.com/users/denoland");
      const jsonData = await jsonResponse.json();
      console.log(jsonData);

      Here you can see that Deno has native support for promises, top level awaits, and even modern Web APIs like fetch.
      Actually in Deno most Web APIs like Websockets, Streams and Crypto work natively, and you can even run WebAssembly code from it.
      Server-only APIs are boxed in the Deno namespace, so if you don’t use them you can easily end up with code that can run in the browser!

      Testing

      Testing is also straightforward:

      import { assertEquals } from "https://deno.land/std@0.117.0/testing/asserts.ts";
      
      Deno.test("My test", () => {
        const x = 5 - 1;
        assertEquals(x, 4);
      });

      You run it with deno test, and it even has support for coverage reports.

      Other bits

      During our session we tried out several APIs and features, including streams and the native support for JSX that makes server side React rendering very straightforward.
      We also tried some third party modules, like the Oak Server which is some sort of Deno equivalent of Express.

      Overall we had a very good time, everything worked as expected and we could accomplish our goals with minimal effort.

      Deno Deploy

      Worthy to mention is also that the Deno Team offers a free (at the time of writing) service to host and run your projects in many regions worldwide simultaneously, automatically serving users from the closest location.

      It is called Deno Deploy, we tried it ourselves and we found its usage extremely simple: just login in https://dash.deno.com/, create a project and point it to a hosted TypeScript/JavaScript file or to a Github Repo.
      No configuration or extra steps are required and it just works.
      It is a bit minimalistic, it doesn’t yet integrate with Gitlab, Bitbucket or other vendors, and it probably isn’t yet a wise choice for serious projects, but it is definitely a good foundation for an interesting offer.

      Troubles in Paradise

      So did we like everything we saw?
      No, we did encounter a couple of minor nuances:

      • The official documentation is quite good, but Deno resources in the rest of the web are very limited compared to more popular technologies like Node
      • We had some issues with tooling support not working as intended (especially involving JSX types recognition in Visual Code)
      • Some code examples we found didn’t work because in the meantime the APIs changed.

      Another doubt about Deno comes from its decision to completely stay away from Node and especially from its ecosystem of thousands of NPM modules.
      Luckily in recent times there have been several steps towards allowing their usage.
      NPM Modules that don’t use the Node API can already be used and there are several services like the excellent Skypack CDN that make it very simple:

      import moment from "https://cdn.skypack.dev/moment?dts";
      console.log(moment().format("MMMM Do YYYY, h:mm:ss a"));

      For the other modules there’s an ongoing effort for adding a Node compatibility layer to Deno .

      Past and Future

      The last remaining doubt is whether Deno can find its place in the crowded space of technology stacks.
      Despite reaching 1.0 last year and a honourable result of more than 79K stars on Github, it has yet to prove itself as a mature technology that is here to stay. Not many companies have adopted it yet in production, and it doesn’t seem like it’s getting a lot of traction in terms of Google Trends, job offerings or other metrics.
      It is definitely not as groundbreaking as Node, and many still doubt whether its runtime and standard libraries are stable enough for mainstream acquisition.

      However it is definitely not a dead horse yet:

      • In March 2021 the Deno company was funded while raising 4.9 millions of dollars in capital to further develop their stack.
      • The Deno Deploy service was announced in June 2021.
      • Slack announced this November that they are using Deno for their next generation platform.
      • Meanwhile the project and its library has seen constant work and improvements.

      There’s still time for Deno to shine, but the next coming months are going to be crucial.

      Last words

      From what we have seen in our short time with it, Deno proved to be a productive, pragmatic and developer friendly technology with a very sound core design.
      Only time will tell if they will succeed in their mission, but we had a great time with it and we will definitely keep a close eye on how it evolves.

       

      Questions?

      Get in touch with us to learn more about the subject and related solutions

      Explore related posts