Deno — Node.js but better

Vishal Khare
5 min readMay 16, 2020

It’s my fault and I’m very sorry. Unfortunately it’s impossible to undo now. — Ryan Dahl (Creator of Node.js)

So there is lot of hype around Deno. If you don’t already know, this is a great place to start.

Mistakes were made

Deno 1.0 was released on 13th May 2020. It was created by Ryan Dahl who is also the creator of Node.js. Apparently when Ryan looked back at design decisions he made and some other aspects of Node.js, he felt like he could have done a much better job (something all developers do). By this time Node.js was extremely popular and so widely used that it was just impossible to fix it due to issues like compatibility, legacy etc. So instead he decided to create a whole new improved project. This new project is DENO

Deno logo
Deno logo

Comparing Deno & Node.js

There are tons of improvements that Deno has over Node.js like promises, build system improvements, doing away with node_modules etc but for now I will just stick with improvements mostly affecting developer experience.

1. Security — Deno is secured by default

JavaScript is a secure sandbox unlike languages like Python but unfortunately Node.js applications can make all sorts of system calls. It has no security. A lot of time, you are not just running your own code. You install a package from NPM and you don’t know what’s in that code. What if it is malicious? Theoretically, it can do anything on your computer.

Deno is secured by default means a Deno app will not have any permission until explicitly mentioned.

Here is a quick demonstration.

This is an example of a simple server which accepts connections on port 8080, and returns to the client anything it sends-

I saved this file as index.ts and then i tried to run it using deno run index.ts. I get following error. It can’t use network resources because i did not explicitly mentioned it while running the app.

Deno permission denied

Now when i use command deno run --allow-net index.ts it works fine.

Deno app with — allow-net flag

To access disk, sub processes, network or environmental variables the user must opt in with a command line flag. Some self explanatory examples are-

--allow-read=/tmp
--allow-write
--allow-net=google.com
--allow-env

2. Import from URLs

A most obvious change in Deno is that you import dependencies from URLs

import { serve } from 'https://deno.land/std/http/server.ts';

Yes. URL goes in including the file extension. This is less ambiguous and it prevents compiler to look for a single file among bunch files with same name but different extensions.

A popular node_modules meme

This is intended to be a replacement of the whole module system. This is more verbose with the benefit of being distributed. It decentralises package management which currently so heavily revolves around NPM. Basically you don’t have a heavy node_modules, package.json or any other of that stuff. You just serve your code through a URL (CDN preferably) and everybody can use that by just importing it. This removes the unnecessary abstraction of node_modules and package.json files.

Note that we did not have to provide the --allow-net flag for this program, and yet it accessed the network. The runtime has special access to download imports and cache them to disk.

Deno caches remote imports in a special directory specified by the $DENO_DIR environmental variable. It defaults to the system's cache directory if $DENO_DIR is not specified. The next time you run the program, no downloads will be made (Unless you specify a --reload flag). If the program hasn't changed, it won't be recompiled either. The default directory is:

On Linux/Redox: $XDG_CACHE_HOME/deno or $HOME/.cache/deno

On Windows: %LOCALAPPDATA%/deno (%LOCALAPPDATA% = FOLDERID_LocalAppData)

On macOS: $HOME/Library/Caches/deno

If something fails, it falls back to $HOME/.deno

To import a specific veriosn — For example, this URL fully specifies the code being run: https://unpkg.com/liltest@0.0.5/dist/liltest.js. Combined with the aforementioned technique of setting $DENO_DIR in production to stored code, one can fully specify the exact code being run, and execute the code without network access.

3. Single executable file

deno bundle [URL] will output a single JavaScript file, which includes all dependencies of the specified input. For example i created a new file index.ts

Now when i run command deno bundle index.ts index.bundle.ts

If you omit the out file, the bundle will be sent to stdout. The bundle can just be run as any other module in Deno would usingdeno run index.bundle.ts

The output is a self contained ES Module, where any exports from the main module supplied on the command line will be available.

Bundles can also be loaded in the web browser. The bundle is a self-contained ES module, and so the attribute of type must be set to "module". For example:

<script type="module" src="index.bundle.ts"></script>

Or you could import it into another ES module to consume:

<script type="module">
import * as website from "index.bundle.ts";
</script>

So this was a quick tour of Deno. Visit https://deno.land for more.

--

--

Vishal Khare

Engineering manager at TATA 1mg || Google Cloud Certified Cloud Engineer