Deno is a simple, modern, and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust. Recently Deno 1.0.5 was released, which is a stable version of the runtime. This post is the first in a series delineating the runtime.
Deno is not that new, as it was first announced in 2018, but it is starting to gain traction, so I thought now would be a perfect time to write about it, considering it could become the next big thing for JavaScript developers.
However, that doesnt mean Node.js will be swept under the rug. Be cautious about people saying Node.js is dead, or Deno is here to replace it entirely. I don’t buy that opinion. Ryan Dahl, the creator of Deno and Node.js, said this in a 2019 conference and I quote: “Node.js isn’t going anywhere.” He also added, “Deno isn’t ready for production yet.”
In this post, we will be discussing Deno’s installation, fundamentals, features, standard library, etc. Everything you will learn here is enough for you to join the Deno train and enjoy what it promises JavaScript developers.
With that said, let’s dive right into the big question: What is Deno? Deno is a runtime for JavaScript and TypeScript based on the V8 JavaScript engine and the Rust programming language. It was created by Ryan Dahl, the original creator of Node.js, and is focused on productivity. It was announced by Dahl in 2018 during his talk “10 Things I Regret About Node.js.”
When I first found out about Deno and the fact that it was created by the creator of Node.js, I had this feeling there must be a significant change, especially in design, so I think we should start going through some interesting features Deno introduced.
This is a list of few of Deno’s features:
Modern JavaScript: Node.js was created in 2009, and since then JavaScript has gotten a lot of updates and improvements. So Deno, as expected, takes advantage of more modern JavaScript.
Top-level await: Normally, when using async/await in Node.js, you have to wrap your awaits inside of an asynchronous function, and you have to label it async. Deno makes it possible to use the await function in the global scope without having to wrap it inside an async function, which is a great feature.
Typescript support out of the box: This is my second favorite feature—there is nothing more fun than having a little more control over your types in projects. This is the reason why I started building most of my projects in Go.
Built-in testing: Deno has a built-in test runner that you can use for testing JavaScript or TypeScript code.
A single executable file: If you have used Golang, the idea of shipping just a single executable file will be familiar. This is now present in JavaScript with the help of Deno. So say bye to downloading hundreds of files to set up your development environment.
Redesigned module system: This is my favorite feature:, Deno has no package.json file, nor huge collections of node_modules. It has its package manager shipped in the same executable, fetching all the resources for you. Modules are loaded onto the application using URLs. This helps to remove the dependency on a centralized registry like npm for Node.js.
Security: With Deno, a developer can provide permission to scripts using flags like --allow-net and --allow-write. Deno offers a sandbox security layer through permissions. A program can only access the permissions set to the executable as flagged by the user. You’re probably asking yourself, “How will I know which flags I have to add to execute the server?” Don’t worry; you will get a message in the console log asking you to add a given flag. Here is a list of the flags:
--allow-env
allow environment access--allow-hrtime
allow high resolution time measurement--allow-net=<allow-net>
allow network access--allow-plugin
allow loading plugins--allow-read=<allow-read>
allow file system read access--allow-run
allow running subprocesses--allow-write=<allow-write>
allow file system write access--allow-all
allow all permissions (same as -A
)No, but this is what I have to say about this constant comparison between Node and Deno. I think you should have an open mind, follow along with the post and get a first-hand experience. In the end, come to your conclusion which one better suits your style. One thing is sure, Deno will get to Node.js level with the attention it is getting recently, and it will be a Node.js successor.
“For some applications, Deno may be a good choice today, for others not yet. It will depend on the requirements. We want to be transparent about these limitations to help people make informed decisions when considering to use Deno.” - Ryan Dahl.
If you already know Node.js and you love TypeScript, or you know any other server-side language, I will give you a big go- ahead. But, if you are starting out learning server-side programming and you want to use JavaScript, I will advise you to learn Node.js first before learning Deno — that way, you will appreciate Deno even more.
Deno ships with a set of standard libraries that is audited by the core team, for example, http, server, fs, etc. And the modules, as stated earlier, are imported using URLs, which is super cool. A module can be imported, as shown below:
import { serve } from "http://deno.land/std/http/server.ts"
Here is a list of Deno standard libraries:
archive
tar archive utilitiesasync
async utilitiesbytes
helpers to manipulate bytes slicesdatetime
date/time parsingencoding
encoding/decoding for various formatsflags
parse command-line flagsfmt
formatting and printingfs
file system APIhash
crypto libhttp
HTTP serverio
I/O liblog
logging utilitiesmime
support for multipart datanode
Node.js compatibility layerpath
path manipulationws
websocketsThere are couple of ways to get Deno installed on your machine.
Using shell (macOS & Linux):
$ curl -fsSL https://deno.land/x/install/install.sh | sh
Using PowerShell (Windows):
$ iwr https://deno.land/x/install/install.ps1 -useb | iex
Using Scoop (Windows):
$ scoop install deno
Using Chocolatey (Windows):
$ choco install deno
Using Homebrew (macOS):
$ brew install deno
Using Cargo (Windows, macOS, Linux):
$ cargo install deno
I’m using Windows so I installed mine using PowerShell:
PS C:\Users\Codak> iwr https://deno.land/x/install/install.ps1 -useb | iex
Deno was installed successfully to C:\Users\Codak\.deno\bin\deno.exe
Run 'deno --help' to get started
To access the deno
command, here’s the support that you can get using deno --help
:
PS C:\Users\Codak> deno --help
deno 1.0.1
A secure JavaScript and TypeScript runtime
Docs: https://deno.land/manual
Modules: https://deno.land/std/ https://deno.land/x/
Bugs: https://github.com/denoland/deno/issues
To start the REPL:
deno
To execute a script:
deno run https://deno.land/std/examples/welcome.ts
To evaluate code in the shell:
deno eval "console.log(30933 + 404)"
USAGE:
deno \[OPTIONS\] [SUBCOMMAND]
OPTIONS:
-h, --help
Prints help information
-L, --log-level <log-level>
Set log level [possible values: debug, info]
-q, --quiet
Suppress diagnostic output
By default, subcommands print human-readable diagnostic messages to stderr.
If the flag is set, restrict these messages to errors.
-V, --version
Prints version information
SUBCOMMANDS:
bundle Bundle module and dependencies into single file
cache Cache the dependencies
completions Generate shell completions
doc Show documentation for a module
eval Eval script
fmt Format source files
help Prints this message or the help of the given subcommand(s)
info Show info about cache or info related to source file
install Install script as an executable
repl Read Eval Print Loop
run Run a program given a filename or url to the module
test Run tests
types Print runtime TypeScript declarations
upgrade Upgrade deno executable to given version
ENVIRONMENT VARIABLES:
DENO_DIR Set deno's base directory (defaults to $HOME/.deno)
DENO_INSTALL_ROOT Set deno install output directory
(defaults to $HOME/.deno/bin)
NO_COLOR Set to disable color
HTTP_PROXY Proxy address for HTTP requests
(module downloads, fetch)
HTTPS_PROXY Same but for HTTPS
The SUBCOMMANDS section lists the commands we can run. You can run deno <subcommand> help
to get specific additional documentation for the command, for example deno bundle --help
.
We can access the REPL (Read Evaluate Print Loop) using the command deno. While in the REPL, we can write regular JavaScript, for example, to add numbers or assign a value to a variable and print the value:
$ deno
Deno 1.0.0
Exit using ctrl+c or close()
> 1+1
2
> const x = 100
undefined
> x
100
>
Let’s touch on two important commands in the SUBCOMMANDS section:
1. Run command
The run
command is used to run a script, whether local or using a URL. To showcase an example, we are going to run a script URL found in Deno’s standard library example section on the Deno official website called welcome.ts
.
$ deno run https://deno.land/std/examples/welcome.ts
Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using master branch https://deno.land/std/examples/welcome.ts
Compile https://deno.land/std/examples/welcome.ts
>> Welcome to Deno 🦕
The output of the script is Welcome to Deno
. You can take a look at the code that gets executed by opening the URL we passed to run
in the browser.
Let’s run another example that will throw an error if we don’t add permission. If you remember earlier, we talked about Deno’s security, and how we need to add flags to give access to the scripts because Deno runs every script in a sandbox.
$ deno run https://deno.land/std/http/file_server.ts
Download https://deno.land/std/http/file_server.ts
Compile https://deno.land/std/http/file_server.ts
error: Uncaught PermissionDenied: read access to "C:\Users\Codak", run again with the --allow-read flag
at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
at Object.sendSync ($deno$/ops/dispatch_json.ts:72:10)
at cwd ($deno$/ops/fs/dir.ts:5:10)
at Module.resolve (https://deno.land/std/path/posix.ts:27:17)
at https://deno.land/std/http/file_server.ts:39:22
Let’s add the required flags and rerun the code. The flags are added immediately after deno run
.
$ deno run --allow-read --allow-net https://deno.land/std/http/file_server.ts >> HTTP server listening on http://0.0.0.0:4507/
Now that our file_server script is running perfectly, you can test it with localhost:4507/
.
2. Install command
The install
command is used to install script as an executable. We are going to use the file_server
script we ran earlier, but this time we are going to install it.
$ deno install --allow-read --allow-net https://deno.land/std/http/file_server.ts
Warning Implicitly using master branch https://deno.land/std/http/file_server.ts
Download https://deno.land/std/path/mod.ts
Compile https://deno.land/std/http/file_server.ts
>> ✅ Successfully installed file_server
C:\Users\<USERNAME>\.deno\bin\file_server.cmd
The file will be downloaded and saved in my base directory C:\Users\username\.deno\bin\file_server.cmd
. If you are on a mac it can be found at /Users/username/.deno/bin``/file_server
.
To run the file, navigate to the base directory folder and run the name of the file file_server
and the server will start up.
$ C:\Users\Codak\.deno\bin> file_server
>> HTTP server listening on http://0.0.0.0:4507/
It will also work if you just run file_server
without navigating to the parent folder:
$ file_server
As a Go developer, I love the go fmt
command used to automatically format Go code; with Node.js, you probably use a third-party package like Beautify or Prettier. Deno ships with a deno fmt
command, just like Go, that automatically formats the script and adds semicolons if omitted anywhere.
$ deno fmt index.ts
So far, we have touched some important aspects of Deno to get an overview of what Deno has to offer. I will leave a couple of resources here for further reading:
Again, if you’re already a server-side developer, I strongly recommend checking out Deno so you can see for yourself what you think. If you’re new to server-side, maybe start first with Node.js so you have a better understanding of what the Deno experience will mean for you.
Chinedu is a tech enthusiast focused on full-stack JavaScript and Infrastructure engineering.