Getting started with Deno.js

Vaibhav Mehta
7 min readMay 17, 2020

--

I’ve been spending a lot of time exploring new tech, trying to make out the most of the Lockdown. From Vue & VueX to Service workers & IndexedDB, it has been a great journey so far. For a few days, there has been a lot of buzz in the engineering community around Deno (I pronounce it as Dee-no), a secure JavaScript & Typescript runtime developed by Ryan Dahl, who previously developed Node.js back in May 2009.

I am working on Node.js for over three years now, and hence, I wanted to explore Deno since it’s very similar to Node and wanted to understand how is it different from Node, and is it any better? At the time of writing this article, Deno announced the 1.0.0 release.

So what is Deno?

Getting Started with Deno Introduction image.
Deno — Secure runtime for JavaScript & Typescript. [OC] Image

Deno is a new runtime for Typescript (and Javascript), a part of it is written in Rust. As Ryan Dahl said in one of his interviews, that Deno acts more like a web browser for command-line scripts. Its security model is that to a browser where websites ask for permission to access the camera, location, etc.

Deno aims to replace utility scripts that were historically written with Bash or Python.

Similarly, Deno scripts run in a secure sandbox without access to the operating system, where users can selectively grant access to the files to provide further functionality. Furthermore, it explicitly takes on the role of both runtime and the package manager.

Features of Deno and how are they different from Node.js

If you’ve worked with Node.js previously, you’ll find Deno quite similar to it but with some significant enhancements around security and the way we import the modules.

Here are some of the features I tried out using Deno and I am highlighting some of them below:

  • Deno is written in Rust as compared to its predecessor, Node.js, which is written in C++.
  • Unlike Node.js, it does not use npm and instead uses modules that are referenced as URLs or file paths. It also embraces the use of ES6 Modules over require statements. For example:
//The Node.js way
const package = require('mypackage');
//The Deno 🦕 way
import package from "https://deno.land/std/SOME_MODULE.ts";
  • Does not use package.json in its module resolution algorithm.
  • All async actions in Deno return a promise. Thus Deno provides different APIs than Node.
  • Support for top-level await unlike Node.js where you need to define async before you can use await. For example:
//The Node.js way
async () => {
let getData = await fetch('URL');
...
}
//The Deno 🦕 way
let getData =
await fetch('URL');
...
  • Requires explicit permissions for files, network, and environment access. Think of a file requesting data from an external resource, and you need to pass a flag like --allow-net to allow the file to fetch the data from an external resource. We will discuss more on this as we write a basic app.
  • It exits if any uncaught errors are encountered. (😨 rip my code, seems like I’ll be spending a lot of time on error handling 😂)
  • Typescript by default. It also eliminates the need for other tools like Babel to compile JavaScript and instead has built-in support.
  • Deno provides a standard library that does not have any external dependencies and is reviewed by the Deno core team. This consists of core modules like DateTime, File System handling, HTTP, etc.
  • Lastly, it has built-in support for necessary testing.

Up & Running

There are numerous ways using which you can install Deno on your system. I’ll share a few examples here:

Using CURL (for macOS & Linux)

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

Powershell (for Windows)

iwr https://deno.land/x/install/install.ps1 -useb | iex

or you can use Homebrew on macOS

brew install deno
A gif to show how Deno is installed using Homebrew on macOS
Installing Deno using Homebrew

For more information, you can refer to the Deno Installation.

Is there a Deno Versioning Manager?

As of now, there’s no official documentation around the version manager. While searching further on this, I came across an open issue on the Deno repo for the same.

In the above, a couple of developers have suggested version managers like asdf-deno and DVM.

Hello World in Deno Land

Let’s take a quick look at a simple example that will highlight some critical features of Deno. You can type the commands directly in the REPL(Read-Execute-Print-Loop) mode, or we can write the code in the .ts or a .js file.

Type deno in the terminal, which will enable the Deno REPL mode.

A gif which shows how to run the Deno runtime using REPL mode
We are running a Deno code in REPL mode.

We can run any JavaScript or TypeScript code (no need of a compiler for TypeScript as Deno natively supports TypeScript).

In the above example, I’ve done some simple math operations like adding two integers and assigning an integer to a constant, which is further used to add to another number.

Lastly, you can exit the REPL mode by typing Deno.exit() or close().

REPL mode is not that useful when running large programs or code snippets, and this is where a file comes handy. We can write our code in a .ts or .js file and execute it using Deno. Let’s create a simple HelloWorld.ts file which will output a simple string.

touch HelloWorld.ts //create a file

Add some code to it. Just a simple console statement for now.

console.log('Hello World');

Note: Writing vanilla JavaScript in the TypeScript file is absolutely fine as mentioned on TypeScript’s website: All valid JavaScript code is also TypeScript code.

And now, let’s run the above file by typing the following command in the terminal.

deno run filepath.ts //outputs Hello World
A gif which shows how to run a simple Hello World app using a TypeScript file.
We are running a .ts file using Deno runtime.

Deno also allows you to run the remote files directly in the terminal like:

deno run https://deno.land/std/examples/welcome.ts
A gif which shows how to run a remote TypeScript file in Deno runtime.
We are running a remote .ts file using Deno runtime.

The above file is one of the examples available in Deno’s Standard Library. You can find more examples at https://deno.land/std/examples.

Our first Deno app

Now that we have some fair idea on how to execute code using REPL or a .ts file, we will now move to a little more complex program where we will explore additional features of Deno.

In the below app, we are merely fetching some data from the third-party website and printing it in the terminal.

We will create a new file for the program, say Request.ts.

touch Request.ts

Add the below code to Request.ts

//fetch the data from JSONBin.io - JSON Storage website (public record)
const getRecords = await fetch('https://api.jsonbin.io/b/5ec136d747a2266b1479ecc7');
//proceed once the promise is resolved from the previous statement, fetch the response body and parse it to json
const getData = await getRecords.json();
//prints the retrieved data
console.log(getData); //[ 1,2,3,4,5 ]

In the above code, we request the JSON data from JSONBin.io (a free JSON hosting website) and later we parse the response using .json() and then we print the response using console.log() statement.

Now, we will run the above code using the following command.

deno run Request.ts

Fair. When we run the file, we expect the file to output the contents we just retrieved, but instead, it errors out.

An error if necessary permissions are not passed to access the network to fetch the data from the third-party website.
Fetching data from a third-party website using the fetch API with Deno

😖 Why is it erroring out? As we discussed earlier, unlike Node.js, Deno provides a secure runtime for JavaScript, and hence, since your script file is trying to access an external resource, you need to grant the permission to the script to do so. Try rerunning the following command, but this time, we will pass the necessary permission for the script to fetch the data.

deno run --allow-net Request.ts//script will now output the contents of the file like 
//[ 1, 2, 3, 4, 5 ]
Running a Deno file by passing necessary permissions to fetch the contents from a third-party website over network.
Run a .ts file to fetch the data from a third-party website

These are some key takeaways from the above app we just created.

  1. We didn’t install any third-party modules like axio , request or node-fetch to request the data as Deno provides us with native fetch API support.
  2. No need to wrap the request with an async function. We can use await directly as it’s available as a top-level function.
  3. We cannot run the program unless the third-party website is granted explicit permission. Hence, we need to pass --allow-net flag explicitly.

Final thoughts

It’s been a couple of days since I started exploring Deno, and I must say, it’s too early to use it in production apps. In the near future, security will be a massive concern for the developers as we’ve already seen malicious packages sneaking in on the NPM registry. There’s also a lack of third-party support, modules that further makes the development difficult as you need to write a lot of modules by yourself instead of focusing on the core functionality of your app.

Deno is not going to replace Node.js any time soon, but in the coming years, you might see Deno community growing, and you’ll see a lot of third-party support like frameworks, modules that will extend the core functionality of the system.

Relevant Resources

I’m sharing a few resources which will help you get started with Deno assuming you already know Node.js.

Leave a clap
Leave a clap if you like; if not, then please leave a response that will help me improve. 🙂

--

--

Vaibhav Mehta
Vaibhav Mehta

Written by Vaibhav Mehta

Engineering Manager @ BrowserStack • 🎮 Gamer • 📷 Amateur Photographer • Design • 🚀 Space • 🍿Popcorn Lover • JSONBin.io Author • More about me @ 8bit.codes

No responses yet