Getting started with Deno.js
Tags: javascript, beginners, deno, node
Published: 2022-11-17 16:30:49

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?
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](https://jaxenter.com/deno-interview-ryan-dahl-171425.html), 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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) over require statements. For example:

```javascript
//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](https://v8.dev/features/top-level-await) unlike Node.js where you need to define `async` before you can use `await`. For example:

```javascript
//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 <u>[standard library](https://deno.land/std@0.165.0)</u> 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](https://deno.land/std@0.165.0/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)
```bash
curl -fsSL https://deno.land/x/install/install.sh | sh
```

### Powershell (for Windows)
```bash
iwr https://deno.land/x/install/install.ps1 -useb | iex
```

or you can use Homebrew on macOS
```bash
brew install deno
```

![Installing Deno using Homebrew](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kt3hkgzf450hwuqql5nc.gif)

For more information, you can refer to the [Deno Installation](https://deno.land/#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](https://github.com/denoland/deno/issues/5214) and [DVM](https://github.com/axetroy/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.

![We are running a Deno code in REPL mode.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lqt0s93n2dr9u62a27mx.gif)

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.

```bash
touch HelloWorld.ts //create a file
```

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

```bash
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.

```bash
deno run filepath.ts //outputs Hello World
```

![We are running a .ts file using Deno runtime.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ynilo09j6ntnvjuu08l7.gif)

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

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

![We are running a remote .ts file using Deno runtime.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z40h824f0znwzoaxjl8d.gif)

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](https://api.jsonbin.io/v3/b/5ec136d747a2266b1479ecc7) and printing it in the terminal.

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

```bash
touch Request.ts
```

Add the below code to Request.ts

```javascript
//fetch the data from JSONBin.io - JSON Storage website (public record)
const getRecords = await fetch('https://api.jsonbin.io/v3/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.

```bash
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.

![Fetching data from a third-party website using the fetch API with Deno](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8gm5ts02izj0mww1dm9b.png)

😖 **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.

```bash
deno run --allow-net Request.ts

# script will now output the contents of the file like 
# [ 1, 2, 3, 4, 5 ]
```

![Run a .ts file to fetch the data from a third-party website](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ms1kbflmc1toq8g8v62.gif)

These are some key takeaways from the above app we just created.
- We didn't install any third-party modules like `axios`, `request` or `node-fetch` to request the data as Deno provides us with native fetch API support.
- No need to wrap the request with an **async** function. We can use `await` directly as it's available as a **top-level** function.
- 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](https://www.google.com/search?q=mailcious+npm+package) 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.

[Deno Repository](https://github.com/denoland/deno)
[Deno Documentation](https://doc.deno.land/)
[Deno Examples](https://deno.land/std/examples/)
[Deno Manual](https://deno.land/manual)
[Deno Standard Library](https://deno.land/std)
[Deno - Third-Party Modules](https://deno.land/x) (more or less like NPM library)
[Top Level fetch](https://v8.dev/features/top-level-await)
[Rust Introduction](https://stevedonovan.github.io/rust-gentle-intro/readme.html)
[TypeScript for beginners](https://www.freecodecamp.org/news/learn-typescript-in-5-minutes-13eda868daeb/)