An Introduction to Deno for Node.js Developers

Rate this content
Bookmark

Deno and Node.js have a lot in common. They are both non-browser JavaScript runtimes built on the V8 engine. Deno and Node.js are also different in a lot of ways: TypeScript, CommonJS, package management, permission systems, tooling, native addons, browser compatibility. This talk will compare and contrast the two runtimes, focusing on what experienced Node.js developers need to know in order to succeed with Deno.

22 min
20 Jun, 2022

Video Summary and Transcription

This Talk provides an introduction to Deno for Node.js developers, highlighting the differences in architecture and dependencies between the two runtimes. It discusses the Deno CLI and integrated toolchain, the Deno standard library and dependency management, as well as the Deno runtime and its core features. The Talk also covers Deno's permission system, its focus on web platform compatibility, and its support for TypeScript. Overall, it provides a comprehensive overview of Deno and its advantages over Node.js.

Available in Español

1. Introduction to Deno for Node.js Developers

Short description:

I'm going to be talking about getting started with deno if you are a node.js developer. I've been using node for about 10 years and just recently started working at deno. Node.js has been around significantly longer since around 2009, and then deno came out around 10 years after that. The interesting thing about node.js is that it predates a lot of what we consider to be modern JavaScript. Dno has taken a different approach, where it's much more batteries included. It has an integrated tool chain and a number of other things. Node.js has a huge ecosystem with a lot of legacy code. Having a huge ecosystem is nice, but having to support so much legacy code can actually slow down a lot of progress and actually kind of hinder Node's ability to have standards compliance.

Hi, everybody. Thanks for coming to my talk. I'm going to be talking about getting started with deno if you are a node.js developer. So a little bit of personal background on myself. I've been using node for about 10 years and just recently started working at deno. So it's been, you know, a learning experience trying to switch between these two environments. So I was hoping that this talk could help somebody else who was in my shoes with moving over to deno.

A little bit of background on both run times. They're both JavaScript run times. They're both built on the V8 engine. Node.js has been around significantly longer since around 2009, and then deno came out around 10 years after that. The interesting thing about node.js is that it predates a lot of what we consider to be modern JavaScript. So for example, it still supports CommonJS, even though it has ES modules. It still has its legacy callback APIs, even though it now has support for a lot of promise-based APIs. Node has also historically, although it has changed a lot in recent years, taken a kind of defer everything to user land approach. So the idea was that core would be very minimal, and that user land would implement NPM modules for a lot of other functionality. I would say that Dno has taken a different approach, where it's much more batteries included. It has an integrated tool chain and a number of other things, which I'll talk about later in these slides. Another thing is that Node.js has a huge ecosystem with a lot of legacy code. This can be good and bad, so having a huge ecosystem is nice. But having to support so much legacy code can actually slow down a lot of progress and actually kind of hinder Node's ability to have standards compliance, which is something else I'll get into later in the slides.

2. Deno Timeline, DenoDeploy, and Growth

Short description:

The timeline for Deno, the release of Deno 1.0.0, the announcement of the Deno company, and the introduction of DenoDeploy. DenoDeploy is a globally distributed JavaScript VM for cloud deployment. The growth of Deno in terms of GitHub stars compared to Node.js. Next, the core technologies under the two projects will be discussed.

So the timeline for Dno is roughly shown here. So in June of 2018, Dno was first introduced at JS Conf EU. Later that year in August, Dno 0.1.0 was released, and it was rewritten in Rust. So initially, the native parts of Dno were written in Golang. And they were kind of moved over to Rust because there was kind of concern about having multiple with garbage collectors running in the same process.

So then in May of 2020, Dno 1.0.0 was was finally released. So then in March of 2021, the Dno company was announced. So this is nice, because having a company backing a project can can really help because you can lay out a roadmap. You can allocate workers to work on specific things, and just generally have better control of how the project is going to be developed. On the other hand, Node.js is run by almost all volunteers. So you know, we can't really, on the Node side, control who's going to work on what. We can't tell volunteers to spend their time on certain features. And we've even had initiatives like Node's Benchmarking Working Group, which is doing a lot of useful work, have to be wound down because there just was nobody that was working on them at the time. So having a company backing the project is huge, in my opinion.

So then in June of 2021, DenoDeploy was announced. So DenoDeploy is a very similar runtime to the open source Deno project, except it's meant to be deployed in the cloud. It's more or less a globally distributed JavaScript VM that lets you run JavaScript programs at the edge all over the world. So there's currently 32 different edge locations that are supported and we're constantly adding more. It's nice because you can write your code and have it deployed in less than 10 seconds globally. And then in Q3 of this year, we are aiming to get DenoDeploy to general availability. And right now it's still in a public beta.

So I wanted to talk quickly about the growth here. So this graph shows GitHub stars for the Deno CLI as well as Node.js. The graph would only generate back to around 2015, even though Node actually goes back to 2009. So that arrow shown there should actually be wider. GitHub stars are kind of a proxy metric for adoption. Anyone can star a GitHub repository without actually using the project. But we do have some internal metrics that indicate that this growth is real and not just fluff on GitHub. So I think based on the 10-year age difference in the two projects, the difference in stars is really something that is worth kind of noting. Next, I want to talk about the core technologies that are under the two projects.

3. Deno and Node.js Architecture

Short description:

Both Deno and Node.js are JavaScript runtimes built on top of V8. However, Deno is written in Rust, which offers memory safety and other advantages over C++. This choice of language influences the project's dependencies.

So as I said earlier, both of these projects are JavaScript runtimes that are built on top of V8, but that is kind of where the architectural similarities stop. So Deno, their native language is written in Rust, whereas Node.js is written in C++, which makes for an easy wrapping around V8 since V8 is also a C++ project. Rust is the new hotness, and it provides things like memory safety and things like that that languages like C++ don't. So it's really nice to be able to work in Rust, but it also dictates what some of the other dependencies are going to look like in the project.

4. A Closer Look at Deno's Architecture

Short description:

Node.js uses LibUV for asynchronous IO and event loop, OpenSSL for encryption, and LLHTTP for HTTP requests. Deno uses Tokyo for asynchronous IO, RustTLS for encryption, and Typer and Requests for HTTP requests. Deno's architecture includes V8 wrapped in Rusty V8, which isolates V8's C++ code from the rest of Deno's Rust code. Rusty V8 also allows precompiled V8s to be shipped. DenoOps provides an API for interacting with the isolate and runtime. Deno deploy builds off open source crates but has a slightly different runtime for cloud deployment.

So for example, Node.js uses LibUV for its asynchronous IO and event loop, whereas Deno uses Tokyo. Node.js also uses OpenSSL, whereas Deno uses a project called RustTLS. On the HTTP side, Node.js uses a project called LLHTTP, whereas Deno uses a couple of projects, Typer and Requests, depending on if you're on the client or server side. And then at the DNS level, it's TrustDNS and Deno versus C-ARIES and Node.js.

So looking a little closer at the Deno architecture, you can see here we have the V8 project wrapped in something called Rusty V8. So Rusty V8 are the Rust bindings to V8. This is what kind of isolates the C++ code of V8 from all of the other Rust code that's inside of Deno. Everything outside of V8 is gonna be in Rust. Rusty V8 also allows you to ship precompiled V8s so that you don't have to compile it on your machine from source, which can take a significant amount of time. And then there is something else inside of the Deno core library called DenoOps, which kind of provide an API for interacting with the isolate and the underlying runtime. So all of this is wrapped up in the Deno core crate. All of these crates are available so that you can actually take and mix and match and create your own runtime if you really wanted to. I mentioned Deno deploy earlier. It actually builds off of all the open source crates, but it does so in a way that the runtime is slightly different because when you're running your local CLI versus running something in the cloud, there are going to be different requirements. And so having a modular approach like this allows you to kind of take advantage of code reuse while still having the different runtimes.

5. Deno and Deno Runtime

Short description:

The core project is a minimal JS runtime wrapped into the Deno runtime, which is a more complete JavaScript runtime. It includes the core, Tokyo for asynchronous IO, and other crates that implement various APIs like DenoFetch, DenoCrypto, and DenoWeb.

So, the core project is kind of a minimal JS runtime, but probably not something that you would want to actually use. The core is then wrapped into another crate called the Deno runtime. So the Deno runtime is a much more complete JavaScript runtime. It's more fun to interact with. It includes the core, it includes the Tokyo for the asynchronous IO. It also includes a number of other crates that implement various APIs. So, some of them are shown here. DenoFetch is used to implement Fetch API, DenoCrypto does crypto stuff, DenoWeb is for a lot of web platform compatibility, and so on and so forth.

6. Deno CLI and Integrated Toolchain

Short description:

The Deno CLI is the executable that you download and run. It includes the Deno runtime and an integrated toolchain, providing everything you need to develop and run Deno applications. It is distributed as a single executable and is available for Linux, macOS, and Windows.

And so then, once you have the Deno runtime, it goes one step further and that is to the actual CLI itself. So this is the executable that you're going to download and run. Deno is distributed as a single executable. You can go get the crates from the Rust package manager if you really wanted to, but most people are just going to download and install this executable, and you can always rely on that executable being the preferred way to download and install Deno.

So the CLI includes the runtime, which I talked about in the previous slide, but it also includes an integrated toolchain. So Deno, as I said earlier, is much more batteries included than Node.js, so you're going to get things out of the box like a linter, a formatter, a test runner, a whole bunch of other things which I'll talk about later in the slides. The idea is that the CLI will have everything that you need to develop and run Deno applications. And this runs on Linux, macOS, and Windows, and I have a link here to the getting started docs if you wanted to step through and download and install Deno on your machine.

7. Deno Standard Library and Dependency Management

Short description:

Deno has a standard library with JavaScript and TypeScript modules maintained by the core team. These modules are audited, guaranteed to be up-to-date, and work well with Deno. They can be versioned independently and are hosted on the internet. Deno's dependency management works like a browser, supporting only ESM and not CommonJS. There is no package.json or node_modules. Deno automatically fetches and caches code, and for production apps, deno-vendor is recommended. There is no NPM, but deno.land/x provides package hosting. Patch releases come out weekly, and semver minor releases come out monthly.

So Deno also has a standard library. So these are going to be JavaScript and TypeScript modules that are built and maintained by the core team. So they're audited and guaranteed to not be stale, not be malware, be maintained, and just generally audited to make sure that they work well with Deno.

I would say that these are on the Node.js side similar to Node's core modules such as FS, HTTP, et cetera. The only difference is that these live outside of the core repository, so they can be versioned independently, released independently, although currently they are released when the core runtime is released as well.

There's a lot of different modules there, things like FS, HTTP streams, things you'd be used to having in Node, UUIDs, WASI, a whole bunch of other stuff. There's not really a package manager for Deno, but these modules are hosted on the internet, so if you go to this deno.land.std, you'll get the latest version of the standard library, and then you can also version these, which is recommended as shown in the example at the bottom here. So if I wanted to import the copy function from the FS library, this is an example of I would do that while also ensuring that I'm getting version 0.141.0, so if there is a breaking change or anything else as the library evolves, you're guaranteed to get a version that you know works with your code.

And so talking about general dependency management, it works a lot like a browser. So there is no NPM. We only support ESM, there's no support for CommonJS. There are CDNs like ESM.sh where you can upload CommonJS modules and they will be transpiled for you, so that you can import them from there. You're not going to have a package.json file, there's not going to be a node modules, there index.js file. So when you do a require, you have to actually specify the file name and not the kind of magical index behavior.

So if you ever use something like Rust, I feel like Deno is kind of similar in the fact that it, when you run your code, it will actually fetch the code. It'll cache it locally so that you don't have to keep installing it. You can even do some work from an airplane if you need to. And it will compile those things automatically for you. So, you know, especially if you're downloading TypeScript, it has to be transpiled and whatnot. But Deno does all of these things for you kind of behind the scenes. And then for production apps, we recommend that you use a command called deno-vendor, which will basically download all of your dependencies locally. And then you can add them to source control or manage them however you want rather than trying to install things at deploy time in production. And as I said, there's no NPM, but there is package hosting at a site called deno.land slash x. So here I'm still showing the example from the previous slide. But if you replace that std at portion of the URL with x, then you would be kind of using, I guess, the Deno equivalent of NPM. And there's a web interface as well. So you can browse there and see all of the different third-party modules that people have created and uploaded. So there is a release schedule. Patch releases come out every week. Semver minor releases come out monthly.

8. Deno Hello World and Tooling

Short description:

These releases usually happen on Thursday. There's not a Semver major release cadence yet like Node.js has, and there's also not an LTS schedule yet like Node.js has, but I do think that those things will come in as the project gets more and more mature. I wanted to quickly look at a Hello World application. So what I'm doing is I'm importing the serve function from Deno's HTTP standard library module, and then creating a handler that the serve function uses every time it receives a request. Some notable features from Deno, focus on web platform compatibility, integrated tool chain, TypeScript support, permission system, and compatibility mode for Node.js code. Deno prefers web platform APIs when possible over rolling their own. Deno has supported web platform APIs since version 1, while Node.js's support is not fully SPEC compliant. Deno has a variety of built-in tools, including Deno lint for linting.

These releases usually happen on Thursday. There's not a Semver major release cadence yet like Node.js has, and there's also not an LTS schedule yet like Node.js has, but I do think that those things will come in as the project gets more and more mature.

So I wanted to quickly look at a Hello World application. So this is only a few lines of code and you can run a full-fledged HTTP server. So what I'm doing is I'm importing the serve function from Deno's HTTP standard library module, and then creating a handler that the serve function uses every time it receives a request. So you can see here we have the request as an input parameter, it's prefixed with an underscore because we're not actually using it. And then this function will return a response. And then all we're returning is a very basic Hello World, and then we call the serve function. When we call serve, it'll actually print to the console what port it's listening on. I believe that's 8000 by default. And then the command here, denorun, allow net server.ts is all you need to actually run this. And I'll talk about what that allow net is in a second.

So some notable features from Deno, focus on web platform compatibility, integrated tool chain, as I already mentioned, TypeScript support is provided out of the box. There's a permission system and there is an actual compatibility mode for Node.js code, which I'll get into in a few slides here. So as far as web platform compatibility goes, Deno almost always, I would say, prefers web platform APIs when possible over rolling their own. So I have a list of some of the web platform APIs that Deno supports here. There are actually even more than this, but they wouldn't fit nicely on a slide. And then on the right side, here, I have a screenshot of the MDN web compatibility tables. So this one in particular is for set timeout. And you can kind of see on the far right here, the last two columns are Deno and Node.js. You can see Deno has supported this since version 1. Node.js supports set timeout, obviously, but it's not really SPEC compliant. So it returns a timeout object instead of a timeout ID. It doesn't support passing in a code string and just different things like that. So web platform compatibility is one of the primary design tenants of Deno and somewhere it really shines.

Tooling comparisons. So there are a lot of tools built into Deno. You can run deno help to see a list of all of the subcommands. Here I have a comparison of some of the very common ones. So for example, the linter, there's Deno lint as opposed to installing ES lint."

9. Deno Tooling and Permission System

Short description:

Same with Prettier, NVM, all of these things are just built into Deno. TypeScript is supported out of the box, and the TypeScript compiler is snapshotted into the Deno binary. SWC, the speedy web compiler, is also built into the executable. Deno's permission system is locked down by default, but you can use CLI flags to grant specific permissions. Deno will prompt you at runtime to allow permissions that have not been explicitly granted.

Same with Prettier, NVM, all of these things are just built into Deno. With the exception of the test runner, which Node does have a built in one. But it's only in the latest version of Node. I think Node is starting to come around more to more batteries included. But as of right now, this is kind of what the tooling landscape looks like.

TypeScript, as I mentioned is supported out of the box. The TypeScript compiler is actually snapshotted into the Deno binary. And then SWC, which is the speedy web compiler. It's a JS and TypeScript tool written in Rust. That's supposed to be 20 times faster for single-threaded applications than Babel is. And I think it's like 70 times faster for multi-threaded. But yeah, all of this stuff is built into the executable. We use that to transpile and bundle and everything like that.

You can configure the TypeScript compiler by passing a config file from the CLI. That's typically not needed. So we don't really recommend it. It's just nice to have an out of the box experience that just works. Deno's permission system is by default Deno is kind of locked down. It can't really access any of the outside world. So we have a list of CLI flags here on the right, which you can use to grant permissions. So if you want to access environment variables, HR time. So high resolution time is behind a CLI flag because it can kind of subject you to timing attacks and things like that. Net for the accessing the network, FFI if you want to load dynamic libraries. Read and write or for reading and writing the file system. Run allows you to run child processes. And if you're just testing and you want to grant all of the permissions, then you have the --allow-all, which is aliased as -a. So you have to explicitly grant these permissions as needed. If something is not granted, Deno will actually prompt you for it and ask at runtime if you want to allow it. One thing to note is if you're running sub processes or FFI, these things are not going to be restricted using the same sandboxing.

10. Deno Permissions and Node Compatibility

Short description:

Deno prompts for permissions at runtime. Sub processes and FFI are not restricted. Flags can be configured for specific access. Node compatibility can be achieved with the --compat flag and allow read for CommonJS. Important links include documentation, standard library, third-party modules, source code, community discord, and Deno Deploy.

If something is not granted, Dino will actually prompt you for it and ask at runtime if you want to allow it. One thing to note is if you're running sub processes or FFI, these things are not going to be restricted using the same sandboxing. So do that with caution. And then some of these flags can actually be further configured. So if I want to read from the file system, but I only want to allow access to a specific directory, I can do that. Or if I want to run a sub process, but only allow running a specific sub process, I can do that as well. And these permissions apply to the whole process and not to individual modules.

So node compatibility. I took a snippet from the docs here. Basically shows how you can create your own require function and then use that require function just like you would in Node.js. So there is no require in Dino by default, but you can do this using the dash dash compat flag. You also have to specify dash dash unstable because this is still considered an unstable feature. And if you want to use common JS, which is what require is then you have to actually specify allow read as well.

Then I have a bunch of what I think are important links or things that people can go as references and look at. The first link is to the primary documentation site the second link is for Deno standard library if you want to browse those third party modules the Deno Land slash x that I had mentioned earlier is there. The source code for the standard library and the CLI are included at Deno Land slash Deno STD and Deno Land slash Deno. There is a community discord that's pretty active so I have the link here if you want to join that and then Deno Deploy the product which is also a different runtime and the globally distributed VM all the things I mentioned earlier. Currently in beta there's a link here if you want to try it out. It does have a pretty generous free tier so I would encourage playing around with it I think it's a pretty nice project but yeah that's everything I had so if you have any questions feel free to reach out to me on Twitter, GitHub or whatever.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2022React Advanced Conference 2022
29 min
Understanding React’s Fiber Architecture
Top Content
We've heard a lot about React's Fiber Architecture, but it feels like few of us understand it in depth (or have the time to). In this talk, Tejas will go over his best attempt at understanding Fiber (reviewed by other experts), and present it in an 'explain-like-I'm-five years old' way.
Node Congress 2022Node Congress 2022
26 min
It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Top Content
Do you know what’s really going on in your node_modules folder? Software supply chain attacks have exploded over the past 12 months and they’re only accelerating in 2022 and beyond. We’ll dive into examples of recent supply chain attacks and what concrete steps you can take to protect your team from this emerging threat.
You can check the slides for Feross' talk here.
Node Congress 2022Node Congress 2022
34 min
Out of the Box Node.js Diagnostics
In the early years of Node.js, diagnostics and debugging were considerable pain points. Modern versions of Node have improved considerably in these areas. Features like async stack traces, heap snapshots, and CPU profiling no longer require third party modules or modifications to application source code. This talk explores the various diagnostic features that have recently been built into Node.
You can check the slides for Colin's talk here. 
JSNation 2023JSNation 2023
22 min
ESM Loaders: Enhancing Module Loading in Node.js
Native ESM support for Node.js was a chance for the Node.js project to release official support for enhancing the module loading experience, to enable use cases such as on the fly transpilation, module stubbing, support for loading modules from HTTP, and monitoring.
While CommonJS has support for all this, it was never officially supported and was done by hacking into the Node.js runtime code. ESM has fixed all this. We will look at the architecture of ESM loading in Node.js, and discuss the loader API that supports enhancing it. We will also look into advanced features such as loader chaining and off thread execution.

Workshops on related topic

React Summit 2022React Summit 2022
117 min
Detox 101: How to write stable end-to-end tests for your React Native application
Top Content
WorkshopFree
Compared to unit testing, end-to-end testing aims to interact with your application just like a real user. And as we all know it can be pretty challenging. Especially when we talk about Mobile applications.
Tests rely on many conditions and are considered to be slow and flaky. On the other hand - end-to-end tests can give the greatest confidence that your app is working. And if done right - can become an amazing tool for boosting developer velocity.
Detox is a gray-box end-to-end testing framework for mobile apps. Developed by Wix to solve the problem of slowness and flakiness and used by React Native itself as its E2E testing tool.
Join me on this workshop to learn how to make your mobile end-to-end tests with Detox rock.
Prerequisites- iOS/Android: MacOS Catalina or newer- Android only: Linux- Install before the workshop
Node Congress 2023Node Congress 2023
109 min
Node.js Masterclass
Workshop
Have you ever struggled with designing and structuring your Node.js applications? Building applications that are well organised, testable and extendable is not always easy. It can often turn out to be a lot more complicated than you expect it to be. In this live event Matteo will show you how he builds Node.js applications from scratch. You’ll learn how he approaches application design, and the philosophies that he applies to create modular, maintainable and effective applications.

Level: intermediate
Node Congress 2023Node Congress 2023
63 min
0 to Auth in an Hour Using NodeJS SDK
WorkshopFree
Passwordless authentication may seem complex, but it is simple to add it to any app using the right tool.
We will enhance a full-stack JS application (Node.JS backend + React frontend) to authenticate users with OAuth (social login) and One Time Passwords (email), including:- User authentication - Managing user interactions, returning session / refresh JWTs- Session management and validation - Storing the session for subsequent client requests, validating / refreshing sessions
At the end of the workshop, we will also touch on another approach to code authentication using frontend Descope Flows (drag-and-drop workflows), while keeping only session validation in the backend. With this, we will also show how easy it is to enable biometrics and other passwordless authentication methods.
Table of contents- A quick intro to core authentication concepts- Coding- Why passwordless matters
Prerequisites- IDE for your choice- Node 18 or higher
JSNation 2023JSNation 2023
104 min
Build and Deploy a Backend With Fastify & Platformatic
WorkshopFree
Platformatic allows you to rapidly develop GraphQL and REST APIs with minimal effort. The best part is that it also allows you to unleash the full potential of Node.js and Fastify whenever you need to. You can fully customise a Platformatic application by writing your own additional features and plugins. In the workshop, we’ll cover both our Open Source modules and our Cloud offering:- Platformatic OSS (open-source software) — Tools and libraries for rapidly building robust applications with Node.js (https://oss.platformatic.dev/).- Platformatic Cloud (currently in beta) — Our hosting platform that includes features such as preview apps, built-in metrics and integration with your Git flow (https://platformatic.dev/). 
In this workshop you'll learn how to develop APIs with Fastify and deploy them to the Platformatic Cloud.
JSNation Live 2021JSNation Live 2021
156 min
Building a Hyper Fast Web Server with Deno
WorkshopFree
Deno 1.9 introduced a new web server API that takes advantage of Hyper, a fast and correct HTTP implementation for Rust. Using this API instead of the std/http implementation increases performance and provides support for HTTP2. In this workshop, learn how to create a web server utilizing Hyper under the hood and boost the performance for your web apps.
React Summit 2022React Summit 2022
164 min
GraphQL - From Zero to Hero in 3 hours
Workshop
How to build a fullstack GraphQL application (Postgres + NestJs + React) in the shortest time possible.
All beginnings are hard. Even harder than choosing the technology is often developing a suitable architecture. Especially when it comes to GraphQL.
In this workshop, you will get a variety of best practices that you would normally have to work through over a number of projects - all in just three hours.
If you've always wanted to participate in a hackathon to get something up and running in the shortest amount of time - then take an active part in this workshop, and participate in the thought processes of the trainer.