Home

Deno, first thoughts

Authored On: Sunday, July 25, 2021

Deno, pronounced “dee-no” like the pet Dinosaur from the Flintstones, is like Go, Rust, and JS had a baby; it can be as flexible as JS and strict like Go when the need (or desire) arises. Why like Rust though? Well, it’s built with the Tokio asynchronous runtime that’s written in Rust. Yep, the entire Deno runtime is written in Rust.

What’s to like though? Well, I think it was quite a bit to offer when compared to Node. For instance, Deno has UUID generation, cryptographic hash generation, and command line flag parsing, ALL in the standard library. In Node, one would need to create some UUID generation and flag parsing from scratch or pull in a third-party module. Other items that are a delight is the ability to do top-level await, fetch is built-in, and it also has built in Typescript support. What’s also worth mentioning is that it includes a permission system built-in. A developer has to pass in CLI flags when running a Deno script in order to access things such as environment variables, the file system, the network, and a few other system resources.

Oh, but the fun doesn’t stop there! Deno comes with some very useful commands in it’s single-file ~30MB built in runtime!

# For auto formating single or multiple supported files in the current project.
deno fmt [files]

# For checking for possible errors using the Typescript engine
deno lint [files]

# For updating the Deno binary
deno upgrade

# For restarting the process automatically on file changes. No more need for nodemon!
deno run --watch 

# For compiling, YES, COMPILING, to binaries
deno compile [options] 

Ok ok, this all sounds great, but here comes the biggest shift to get used to…


There is no package manager.
Yes. You read that right. No package manager; no NPM equivalent. So then how does Deno use third-party modules? Well, it uses the import command to pull in ES Modules from remote files (or local). Take a look at the following snipped for instance:

// mod.ts
confetti from "https://cdn.skypack.dev/canvas-confetti";

confetti();

Upon executing deno run ./mod.ts, Deno would check to see if that files exists in the local repo cache, if it doesn’t, Deno would pull that package down from and then continue to run the rest of the script. Now, there’s plenty of upsides to this approach.

For one, there’s no need to remember to do an npm install between git pulls. This eliminates the need to remember or automate this step in a development workflow.

Two, no per-project dependency folder. Ever been curious enough to see how space node_modules is taking up on your project? Yeah, it’s a folder than easily reach upwards of 500 MB and silently eat up file space with duplicate files across local projects.

For the cons… it’s not easy to bulk bump minor or patch versions of dependencies using a CLI command. Many third-party Deno repo sites, such as the main Deno repo site version their URLs by adding a version suffix after the package name e.g. https://deno.land/[email protected]/http/server.ts. One has to manually update the version in the URL and this can get a bit tedious. One could argue that project contributors/owners shouldn’t be bulk updating deps… but some deps like eslint isn’t likely to take down a entire project if it’s bumped a patch (or heck, even a minor) version.

The other downside, and the biggest in my opinion, is the large incompatibility with existing Node modules hosted on NPM. While there’s a growing number of packages that are starting to be migrated to the Deno repository, it’s not easy to port packages over. For example there’s no process global variable, that means, any Node modules that use environment variables for instance such as the golden boy process.env.NODE_ENV would have to switch to a syntax such as Deno.env.get("NODE_ENV"). What seems a bit counter-intuitive though, is that it’s actually easier to migrate browser packages over to Deno than Node packages. This is because Deno decided to implement browser globals over Node ones. So, globals like alert, confirm, and YES even localStorage work on Deno.

While Deno is still a small community, I see a lot of potential in this project. They’ve taken some interesting approaches in the way it’s built and some of the features it’s chosen to adopt. Is it a worthy contender to Node? I think so, but I hope that Node can also learn from some of the great things Deno is throwing in out-of-the-box such as process auto-reload. I can’t wait to see how far this dinosaur can go.

Home