Back to Blog

Have you tried Deno yet?

Hello everyone! This blog post will provide a brief introduction to Deno - a secure runtime for JavaScript and TypeScript - with a code-along where we introduce some of Deno's coolest features.

Argentinosaurus_skeleton - Deno logo is a dinosaur

What is Deno?

Did you notice “Deno” is an anagram of “Node”? That’s for a reason. Deno was created by Node’s author, Ryan Dahl. He first revealed it in a talk in 2018 called 10 Things I Regret About Node.js, where he described how he attempted to right the wrongs of his own past design decisions.

Deno is essentially a better, more secure and shinier alternative to Node. The major appeal, as we will see in this code-along, is Deno’s lack of clutter and clunk. This makes the runtime particularly suitable for beginners, because you don’t have to worry about random files and directories like package.json or /node_modules. Deno doesn’t need that nonsense, and neither do you.

How to get started with Deno?

All the code used can be found on GitHub at minnacaptain/have-you-tried-deno-yet, but you don’t need to clone the repo to follow along.

Install Deno

Go to deno.land and follow the installation instructions. I’m using version 1.12.1.

Install the VSCode extension

I use Visual Studio Code as my editor of choice and thoroughly recommend it. To have a good time while using Deno, you should install the Deno extension.

Get the example data

Download this text file from Github onto your computer. It contains a list of imaginary students who have taken imaginary AWS exams – and generally scored very poorly. We will parse this data and calculate their average score.

Install TypeScript?

You do not need to install TypeScript separately, because it comes bundled with Deno.

Check it out yo

% deno --version

deno 1.12.1 (release, x86_64-apple-darwin)
v8 9.2.230.14
typescript 4.3.5

Open up your VSCode editor

From your Downloads folder.

What?

Yes.

Embrace the barbarian within you. Then create a file called parseStuff.ts.

Deno Blog: parsestuff file screenshot

Open the command palette (Cmd+Shift+P) and select Deno: Initialize Workspace Configuration. This will enable you to use auto-complete.

Now let’s read that example_data.txt file that we downloaded earlier, and start parsing lines.

Embedded content: https://gist.github.com/minnacaptain/c30d440a0d11daf6d348e8ec04c0e903.js

Before we proceed, let’s try to run the code to see if we’ve messed something up.

Open up a terminal window, and try to run the code:

% deno run parseStuff.ts

Check file:///.../Downloads/parseStuff.ts
error: Uncaught (in promise) PermissionDenied: Requires read access to "./example_data.txt", run again with the --allow-read flag
    at deno:core/01_core.js:106:46
    at unwrapOpResult (deno:core/01_core.js:126:13)
    at async open (deno:runtime/js/40_files.js:51:17)
    at async Object.readTextFile (deno:runtime/js/40_read_file.js:40:18)

Ah, okay, yes I’m a programmer and I read error messages. Therefore I quickly understand that we need to use the --allow-read flag.

This is intentional, and it’s one of the cool security features of Deno. You have to explicitly state whether a Deno program should be allowed to read files on your filesystem.

Try again:

% deno run --allow-read parseStuff.ts

Check file:///.../Downloads/parseStuff.ts
[
  [
    "student_name",
    "horoscope",
    "exam_name",
    "exam_score",
    "feedback_score",
    "would_recommend"
  ],
  [
    "Braylen Natalia",
    "Gemini",
    "AWS Certified Cloud Practitioner",
    "5.72",
    "4.26",
    "Yes"
  ],
  [
    "Kash Macey",
    "Leo",
...

Looks about right.

Let’s continue writing the boilerplate for calculating average scores:

Embedded content: https://gist.github.com/minnacaptain/dd1c2bba09105da18805f2d6ff16cc82.js

Running this gives us an average score of 6.7556.

% deno run --allow-read parseStuff.ts

Check file:///.../Downloads/parseStuff.ts
Average score: 6.7555000000000005

Good!

Taking the data from the internet

Maybe I don’t want to get this example data from my local file system. Perhaps I would rather get it straight from the internet – for example, if some fresh noob takes an AWS exam and the file gets updated with the score. Let’s change up the getContent function:

Embedded content: https://gist.github.com/minnacaptain/bd710e68216c2a8ed2fc976d63574050.js

And let’s run it:

% deno run --allow-read parseStuff.ts

Check file:///.../Downloads/parseStuff.ts
error: Uncaught PermissionDenied: Requires net access to "raw.githubusercontent.com", run again with the --allow-net flag
    fetch(
    ^
    at deno:core/01_core.js:106:46
    at unwrapOpResult (deno:core/01_core.js:126:13)
    at Object.opSync (deno:core/01_core.js:140:12)

Ah yes, security again. I shouldn’t just download any old trojan from the internet. This can be easily fixed by using the correct flags (I know, because I read error messages).

Let’s try again:

% deno run --allow-net parseStuff.ts

Average score: 6.7555000000000005

Excellent, it works.

Writing tests with Deno

First, install the testing library.

Lol, just kidding! There is no step to install the testing library.

The actual first step is to put the calculateAverageScore function into its own file, called calculate.ts:

Embedded content: https://gist.github.com/minnacaptain/3692ead6e297e45bd7d6ab34c4256cef.js

Then create a test file, calculate.test.ts, and write a few lines of test code. We will mock the getContent function by taking the first three lines from example_data.txt, then fudge the scores to 1, 2, 3 so that they average 2.

Embedded content: https://gist.github.com/minnacaptain/0236d947cebaab73246a9ff9cea262e7.js

Let’s have a look at the first line, import { assertEquals } from "https://deno.land/std@0.102.0/testing/asserts.ts";

A couple of differences to note between Node and Deno. In Deno, we import code libraries with URL syntax. Once the library is used once, its contents are cached, so there isn’t a new network request each time you subsequently run your code. Note also that for Deno imports, filenames are fully specified (.ts). Local files are also imported with extensions.

Back to the test, let’s run it:

% deno test calculate.test.ts

[…]
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (30ms)

Neat! We didn’t have to install any libraries, we just imported assertEqual and we’re done.

Getting your functions from the internet

If I now decide I want to publish and distribute my average score calculator function to other developers, I can do this very easily. Host the calculate.ts file anywhere on the internet and it can then be imported in its raw form in Deno code:

Embedded content: https://gist.github.com/minnacaptain/7bd35b3ec85e6bd3bc111e3ab6f79597.js

Does it work?

%deno run --allow-net parseStuff.ts

Download https://raw.githubusercontent.com/minnacaptain/have-you-tried-deno-yet/master/calculate.ts
Check file:///Users/minna.niemi@futurice.com/Source/have-you-tried-deno-yet/parseStuff.ts
Average score: 6.7555000000000005

Yes it does, very good!

End of code-along. What’s the takeaway?

Look at our directory (yes, I know, it’s the Downloads folder, but try to ignore your sensibilities for a moment).

Where’s node_modules? Nowhere to be seen. Where’s package.json? Not there. Where is, umm, tsconfig.json? Who cares?!

Deno Blog - Heavy Objects

I remember when I was young and stupid, and I was being introduced to new-age JavaScript with its ES6 and modules and npm. The main problem was that I couldn’t tell how all those files created by npm init interacted. Which ones were magic? Which ones weren’t? And how do I put TypeScript in here? And the countless, countless rm -rf node_modules && npm install cycles. Also, what’s yarn?

Package management tends to be an afterthought, its form evolving over time as users of programming languages and runtimes develop dire needs to distribute code and borrow code from each other. And there are varying levels of elegance! For example, I’ve had a terrible experience every time I try to use Python packages: there are multiple managers, and it’s not clear which one is best. On the other hand, package management for something like C# is very user-friendly with NuGet.

While package management in Node isn’t the worst, Deno makes it even better. The runtime is designed with simplicity of package management in mind, and it shows. This is what programming with JavaScript should be like.

Deno Blog: Marie Kondo

But what about the Deno ecosystem?

The one (giant) thing that’s missing from Deno is a rich ecosystem. Deno isn’t directly compatible with Node – it’s not meant to be. But it does mean that there aren’t nearly as many libraries available.

What’s the solution? Start writing those plugins and libraries that you need yourself. Remember: open source is YOU.


To follow the code-along in video format, listen to the full TechWeeklies talk here. And checkout more tech talks on our TechWeeklies page.

Author

  • Portrait of Minna Captain
    Minna Captain
    Developer