Node.js has been reigning high in the javascript world for the past 8 years.
But now there is a new contender on the block.
Deno.
Which, if you haven't noticed, is just the letters of Node rearranged.
But what is Deno? A language? A runtime? A package manager?
Let's dive in and find out.
👇 The low down
Deno is a project which was created by the original creator of Node.js, Ryan Dahl and has just gone 1.0.
It's is defined on its website as:
> A secure runtime for javascript and typescript
It's not a new language, it's not a new type system but rather a new runtime, one that supports javascript and typescript out of the box.
But it's actually so much more.
♤ Digging Deeper
Let’s break apart these claims and go through them one by one.
Secure Runtime
Firstly, let's look at one of the more prominent claims of the Deno project, the secure runtime.
What is a runtime? Well, javascript has two components, the engine and the runtime.
The engine is what takes the code you've written and converts it into executable code.
The runtime, on the other hand, is what gives your code an environment or context to run in. It provides a set of objects and API's that your code can interact with, for example, things like the filesystem or `window`.
Both the browser and node.js use the same engine - the V8 engine (there are different engines out there, V8 is just one of the more popular). However, they don't use the same runtime.
The browser is going to use the runtime provided by the browser and node.js is going to use the runtime provided by, well, node.js.
Deno provides a new runtime for the javascript or typescript code you write.
More importantly, it provides a secure runtime.
What do they mean by secure?
Well, with Node.js, you are putting a lot of trust in the fact that the scripts you use aren't doing anything shifty.
For example, take the following code. Here I have imported a module 'i-am-totally-safe'. I am under the impression that this module will take some text, and given a language, convert it said language
If I executed this using the Node.js runtime, I would have to trust that this code isn't doing anything malicious, because, by default, the Node.js runtime provides access to the entire system for any script.
For example, the above script I imported, when run, could actually scan my system for environment variables (DB Hosts, usernames and passwords) and send them off to a third-party system. All without me knowing.
You are relying on that the code you execute is safe and verified. Usually, you assert this through some sort of social proof. If a package is downloaded 1 million times per week, then chances are it's going to be safe right?
Because not only do you have to verify that every package you use is safe, you also have to ensure that every package that package uses is safe, and every package that uses is safe.
You get the picture.
However, if you run the above code in the browser, then chances are you are somewhat more protected. By default, the browser prevents access to most things, hard drives, webcams, microphones etc.
This makes sense right - you don't want to accidentally visit a webpage and suddenly have the entire contents of your hard drive encrypted.
This is because the browser runtime is secure and has a somewhat 0 trust level of scripts executed within it. The user has to explicitly grant access.
So that is the same level of security that Deno is trying to provide. They want to bring the disabled by default nature of the browser, to the server-side.
They do this by sandboxing your code.
This means that by default your code can not:
Access the filesystem
Access the network
Access the environment
To allow this, you have to explicitly enable access by providing a flag when executing your code.
To illustrate, given the following example from the Deno docs:
If we were to run it with:
deno run myWebserver.ts
This would in fact not actually work. This is because we haven't provided it with permission to access the network. To do so, we have to give the `--allow-net` flag:
deno run --allow-net myWebserver.ts
There are a few issues with this approach, mainly that if one script needs access to the net, then all scripts will now have access. However, there are some workarounds for this by using the API explicitly inside the code.
Still, by default, this is a significant step forward for writing secure applications.
Dependency Management
Now Deno handles dependencies very differently to Node.js.
Typically with Node, you would simply include a package.json file in your project's directory and then reference your dependencies in your import statements.
With Deno, the way they handle dependencies is quite different, and probably the most controversial feature of the runtime.
With Deno, you use URLs, pointing directly to the source of the file.
import { Response } from "https://deno.land/std@0.53.0/http/server.ts"
Here we are pointing directly to the STD library HTTP server.ts file, and pinning it to version `0.53.0`.
This makes it incredibly trivial to quickly write scripts that utilise dependencies without having to set up a node project with a package.json file.
However, obviously, it has some downsides.
Mainly, version management. If I use the same package in multiple files (say a UUID generator), I have to ensure that everywhere I import that file, I use the same version. If I need to bump that version I now need to update it everywhere as well.
Obviously, this is a bit of pain.
Currently, there are a couple of solutions that people are coming up with, however probably the most prevalent will be import maps, which is presently an unstable feature form the Deno team.
Import Maps are an experimental feature from the Deno team that acts more like the traditional package.json file.
Either way, all dependencies are cached by default, so don't worry if you were thinking it was going to re-download them on every execution.
Standard Library
One of the biggest positives of Deno, in my opinion, is the standard library.
This is something really is missing from Node and has lead to multiple competing packages, all trying to do something that should have been incorporated into the language in the first place.
Personally, I feel the lack of the std library for Node.js is what has a led to such a diverse set of contrasting and incomplete approaches to writing Node.js applications.
Obviously, some would see this as a positive - you now aren't locked into one approach or way of doing things. However, I'd argue that I'd prefer to have a community accepted approach or library that's used for a single task and optionally, if I didn't like that approach, then I could use an alternative package.
Enough of my rant though. Back to Deno.
The best feature of the standard library is that the Deno team is guaranteeing that the code there will always be audited. This means that for widespread packages, like HTTP servers and uuid's that you can be sure the code that is being run is safe to use.
The standard library includes modules like HTTP, WS, UUID, Hashing, DateTime - the list goes on.
You can check out all the modules here.
Typescript support...by default
Javascript is great. But... in saying that it has a few quirks and can work in some unexpected ways.
Typescript is a great alternative, built on top of Javascript that provides a reasonable type system that can help catch a plethora of runtime errors, during compilation.
Previously, if you were using typescript with Node.js, you would need to include a typescript compiler, typescript config etc.
However, with Deno, it works straight out of the box.
deno run myfile.js works exactly the same as running deno run myfile.ts. No particular configuration or systems needed.
Although, you are obviously able to provide your own config if you'd like.
Currently, they are using the Microsoft typescript compiler, but have plans to implement their own complier in rust.
Single Executable
Unlike Node.js, where once built/compiled (if using typescript) you are given a set of files, with a single entry point, Deno will always give you a single executable binary.
$ deno bundle ./myEntrypoint.ts myProgram.bundle.js
$ deno run myProgram.bundle.js
This is obviously much easier in terms of portability.
🙋♂️ Enjoying this article?
If you’re enjoying this article and want to see more like it - then subscribe to Breadth to get these delivered straight to your inbox weekly.
🤷♂️ When would you use it?
Deno is a great new alternative to Node.js.
I wouldn't go as far as to say that it's a replacement just yet.
It has a few tradeoffs that I mentioned above and is still quite young - and therefore susceptible to quite a few changes.
However, it does have a promising future, and I would definitely recommend getting your feet wet with it.
I'm not saying go out and build your next application in Deno - but maybe next time you have a small script you want to run, give it a shot.
💯 Gimme More
This post was definitely aimed at given you surface-level knowledge about Deno, increasing your Breadth.
If you want to increase your depth, then check out the below:
🧩 This weeks puzzle
This weeks puzzle is around the thing that makes the world spin.
Money.
In Australia 🇦🇺we have the following coins:
5¢ 10¢ 20¢ 50¢ $1 and $2 coins.
One way of making up $3 is by:
$1 + 50¢ + 50¢ + 50¢ + 20¢ + 20¢ + 10¢
What is the total number of ways you can create $3 out of the 6 above listed coins?
Reply to the below with your answer!
1022 ways