If you have been a Node JS developer like me, you now have something to be excited about. We have a new competitor in town - Deno. Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust.
How is Deno different from Node?
If you are a Node JS developer, you might be aware of its callback based architecture. Unfortunately callbacks are a thing of the past. We now have Promises. Deno supports Promises out of the box. Not only that it provides many more features -
- Out of the box TypeScript support. No more manual compiling.
- Top level await.
- Secure by default. A Deno app doesn't have access to filesystem, network or environment variables by default unless you allow them.
- No package manager like
npm
. No hassle of installing packages manually. - Built in Has built-in utilities like a dependency inspector (deno info) and a code formatter (deno fmt).
- Deno aims to be browser compatible as much as possible. It provides a built-in
fetch
and globalwindow
object.
A Short History
Deno was announced in 2018 at the JSConf EU by Ryan Dahl, who is the original creator of Node JS (https://www.youtube.com/watch?v=M3BM9TB-8yA). According to him, there are many decisions he took that he dislikes about Node. Technology changes swiftly and over the years JS has changed a lot and so Ryan created Deno to take advantage of the improved features of JS.
The first stable release of Deno is Deno 1.0 which released on May 13, 2020.
Let's Dive Into Coding
Enough talk, let's get our hands dirty with Deno. First we will install Deno. It's just a single binary and installing it is as simple as running one command -
curl -fsSL https://deno.land/x/install/install.sh | sh
By default the binary is installed in $HOME/.deno/bin
and so we need to add it to our $PATH
. Add this line to your .bashrc
or .zshrc
export PATH=$HOME/.deno/bin:$PATH
or if you're using fish
like me, add this to your .config/fish/config.fish
set -gx $HOME/.deno/bin $PATH
Now we can get started with some real code.
We can run deno
without any other options, or deno repl
to start a REPL
![](https://blog.abhattacharyea.dev/content/images/2020/05/Screenshot_20200514_213057.png)
Let's run your first app. One of the amazing features of Deno is that you can run apps straight from the url without even having to write a single line!
deno run https://deno.land/std/examples/welcome.ts
![](https://blog.abhattacharyea.dev/content/images/2020/05/Screenshot_20200514_213255.png)
As you can see, Deno downloads the file from the URL and compiles and runs it. If you run the command again, it will not download the file again and will use the previously downloaded file.
![](https://blog.abhattacharyea.dev/content/images/2020/05/Screenshot_20200514_213703.png)
Now let's run a more complex code. Create a file called first.ts
and write the following code
import { serve } from "https://deno.land/std@0.50.0/http/server.ts";
const s = serve({ port: 8000 });
console.log("http://localhost:8000/");
for await (const req of s) {
req.respond({ body: "Hello World\n" });
}
The first thing you should have noticed that we can import directly from the URL. There is no need to install a package. If you visit the URL in your browser, you'll see it is just a TypeScript file -
![](https://blog.abhattacharyea.dev/content/images/2020/05/Screenshot_20200514_220925.png)
We are importing the serve
function from this file -
![](https://blog.abhattacharyea.dev/content/images/2020/05/Screenshot_20200514_221033.png)
We are assigning the port 8000
to the server and in the for loop we are responding to "Hello World" to each request. Observe that we can use await
directly in the for loop without wrapping it inside any async
function. It's because Deno has top level await
.
Let's run this program.
deno run first.ts
![](https://blog.abhattacharyea.dev/content/images/2020/05/Screenshot_20200514_221450.png)
As you can see, Deno downloads the file at the URL but it has its own dependencies and Deno downloads all of them and caches them.
Although we have an error
error: Uncaught PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag
at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
at Object.sendSync ($deno$/ops/dispatch_json.ts:72:10)
at Object.listen ($deno$/ops/net.ts:51:10)
at listen ($deno$/net.ts:152:22)
at serve (https://deno.land/std@0.50.0/http/server.ts:261:20)
at file:///home/aniket/deno/first.ts:2:11
This is because Deno runs in a sandbox by default and can't access the network unless the permission is explicitly granted with the --allow-net
flag.
deno run --allow-net first.ts
Now you should be able to visit localhost:8000
in your browser and see the response.
Further Reading
You can find more info about Deno in the official website. The docs are available at https://deno.land/manual/introduction and the standard library is available here