Deno VS Node

and the neverending challenge of JavaScript runtimes

Ryan Dahl

What is Deno?

What are the main differences with Node.js?

Installation

Shell (Mac, Linux)

$ curl -fsSL https://deno.land/x/install/install.sh | sh

PowerShell (Windows)

$ iwr https://deno.land/x/install/install.ps1 -useb | iex

Homebrew (Mac OS)

$ brew install deno

Let’s take a look at security

async function main () {
const encoder = new TextEncoder ()
const data = encoder.encode ('Hello Deno! 🦕 \n')
await Deno.writeFile( 'hello.txt' , data)
}
main()
$ deno run hello-world.ts
Check file:///home/davide/denoExample/hello-world.ts
error: Uncaught PermissionDenied: write access to "hello.txt", run again with the --allow-write flag
at unwrapResponse ($deno$/ops/dispatch_json.ts:42:11)
at Object.sendAsync ($deno$/ops/dispatch_json.ts:93:10)
at async Object.open ($deno$/files.ts:38:15)
at async Object.writeFile ($deno$/write_file.ts:61:16)
at async file:///home/davide/projects/denoExample/hello-world.ts:5:3
$ deno run --allow-write hello-world.ts

A simple server

// file server.ts
import { serve } from 'https://deno.land/std/http/server.ts'
const s = serve({ port: 8000 })
console.log('Server listening on port :8000')
for await (const req of s) {
req.respond({ body: 'Hello Deno!\n' })
}
$ deno run --allow-net server.ts

Modules

import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

I need to type the URL every time? 🤯🤬

{
"imports": {
"fmt/": "https://deno.land/std@0.65.0/fmt/"
}
}
// file colors.ts
import { green } from "fmt/colors.ts";
console.log(green("Hello Deno! 🦕"));
$ deno run --unstable --importmap=import_map.json colors.ts

Versioning

https://unpkg.com/package-name@0.0.5/dist/package-name.js

Ready to use utilities

Photo by Ryan Snaadt on Unsplash

Bundler

// file colors.ts
import { green } from "https://deno.land/std@0.65.0/fmt/colors.ts";
console.log(green("Hello Deno! 🦕"));
$ deno bundle colors.ts colors.bundle.js
$ deno run colors.bundle.js

Debugger

$ deno run -A — inspect-brk fileToDebug.ts

Dependency inspector

Doc generator

/**
* Adds x and y.
* @param {number} x
* @param {number} y
* @returns {number} Sum of x and y
*/
export function add(x: number, y: number): number {
return x + y;
}

Formatter

Test runner

import { assertEquals } from "https://deno.land/std/testing/asserts.ts"

Deno.test({
name: "testing example",
fn(): void {
assertEquals("world", "world")
assertEquals({ hello: "world" }, { hello: "world" })
},
})

Linter

# This command lint all the ts and js files in the current working directory
$ deno lint --unstable
# This command lint all the listed files
$ deno lint --unstable myfile1.ts myfile2.ts

Benchmark

Model: XPS 13 9380
Processor: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
RAM: 16GB DDR3 2133MHz
OS: Ubuntu 20.04 LTS
Kernel version: 5.4.0-42
// file node_http.js
const http = require("http");
const hostname = "127.0.0.1";
const port = 3000;
http.createServer((req, res) => {
res.end("Hello World");
}).listen(port, hostname, () => {
console.log("node listening on:", port);
});
// file deno_http.ts
import { serve } from "https://deno.land/std@0.61.0/http/server.ts";
const port = 3000;
const s = serve({ port });
const body = new TextEncoder().encode("Hello World");
console.log("deno_http listen on", port);
for await (const req of s) {
const res = {
body,
headers: new Headers(),
};
res.headers.set("Date", new Date().toUTCString());
res.headers.set("Connection", "keep-alive");
req.respond(res).catch(() => {});
}

Conclusion

HAPPY CODING!

Bibliography

👨‍🎓Degree in computer science 💑 Married with Milena 🤓 Huge Nerd! 💻 Code lover 👨🏻‍💻 Fullstack developer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store