Deno is a JavaScript runtime environment. If you’re familiar with Node.js, you might wonder why you should consider Deno. It’s worth noting that Deno was developed by the creator of Node.js to address its limitations and shortcomings and to provide a superior alternative for modern web development. So, Let see why I found that Deno is better than Node.js, and how it can simplify the development of reliable web apps.
Deno has native support for TypeScript
JavaScript, while easy to use, lacks a robust type system that would make building larger projects more manageable. TypeScript’s static typing provides a more solid code structure, better tooling, and increased maintainability, which is especially beneficial for larger projects. As a result, TypeScript is becoming the first choice for developing new projects.
However, Node.js doesn’t support running TypeScript files directly. To execute a TypeScript file, you must compile it to JavaScript, which can then be run by the Node.js runtime. Alternatively, tools like ts-node let you run TypeScript files without needing to compile them to JavaScript first.
In contrast, Deno offers native TypeScript support out of the box, allowing developers to run TypeScript files directly without compilation. It is excellent news for anyone like me that get frustrated while his typescript config file and compilation flow breaks each time when he update his dependencies.
Let’s see it action, let’s create a script that display a nice greeting from deno
# main.ts
export function hello(name: string): string {
return `Hello from ${name}`;
}
console.log( hello('Deno'));
To execute it in the Node.js runtime environment, we first need to compile it to JavaScript and then run the compiled JavaScript file.
$ npm install -g typescript
# ...
$ tsc main.ts && node main.js
Hello from deno
Alternatively, We can also use the ts-node tool to skip the compilation step.
$ npm install -g ts-node
# ...
$ ts-node main.ts
Hello from deno
Clearly, in both cases, additional tools are required to execute the TypeScript file using the Node.js runtime. However, no extra tools are needed to execute the file with Deno.
$ deno run main.ts
Hello from deno
As we can see, no additional tools are required to execute the TypeScript file using the Deno. With Deno – Typescript just works without any effort.
Deno follows web standards
As a Node developer, you’re likely aware that not all code written for Node.js Runtime will easily function in a browser. Some APIs supported by the Node.js Runtime environment are not supported by the browser’s JavaScript Runtime. To enable running Node.js code in a browser, you’ll need to use tools like Browserify, Webpack, or Webmake to transpile, build and bundle your scripts. Although this is achievable, It may be complicated, time consuming and requires the effort of learning these additional tools, as well as understanding their limitations and potential pitfalls.
Originally, the Node.js Runtime had to develop APIs that were absent in the browser’s JavaScript Runtime. However, with the addition of new APIs to the browser’s JavaScript Runtime over time, the two Runtimes have diverged. Now, they use distinct APIs to perform the same functions.
For example, let’s say we need to make an HTTP request from a REST endpoint. Here is one way we can do it with Node.js with https package
// http-1.js
const https = require('https');
https.get('https://jsonplaceholder.typicode.com/todos/1', res => {
const data = [];
res.on('data', chunk => {
data.push(chunk);
});
res.on('end', () => {
const task = JSON.parse(Buffer.concat(data).toString());
console.log(`Task #${task.id} => ${task.title}`);
});
}).on('error', err => {
console.log('Error: ', err.message);
});
However, the above Node.js code will not work in the browser. To make an HTTP request from a REST endpoint successfully, we must use the standard fetch API
// http-2.js
fetch('https://jsonplaceholder.typicode.com/todos/1').then( res => {
res.json().then( task => {
console.log(`Task #${task.id} => ${task.title}`)
});
}).catch( err => {
console.log('Error: ', err.message);
});
As we can see, writing code that works in both Node.js and the browser is not trivial, as they use distinct APIs. Deno adheres to web standards such as the fetch API, which enables us to run the above code without any modifications.
$ deno run --allow-net http-2.js
Task #1 => delectus aut autem
Deno adheres to web standards and APIs, allowing you to write code that is compatible with both the Deno runtime and the browser. This compliance with web standards and the provision of browser-like APIs allow developers to write code once and use it in both environments, saving time and effort. This compatibility with both Deno and the browser is a significant advantage of using Deno over Node.js. Therefore, If you’re familiar with the web, you’ll be productive with Deno immediately.
Deno makes your life easier
Deno provides tools to ease your life. It offers built-in tools for building, testing, formatting, and benchmarking your code. While a similar toolchain can be established with Node.js, it requires time for tool installation, configuration, and learning. In contrast, Deno enables effortless productivity, allowing you to start writing your application immediately.
Deno simplifies common tasks such as writing a web server. With just a single line of code, you can quickly have a web server up and running. There’s no need for third-party code; simply use what Deno provides out of the box.
// server.js
Deno.serve( req => new Response("Hallo from Deno\n") )
$ deno run --allow-net server.js &
Listening on http://localhost:8000/
[1] 91232
$ curl http://localhost:8000/
Hallo from Deno
Deno is Secure
The Node.js Runtime environment enables various tasks on the computer, such as reading and writing files, and making network requests. Despite offering a robust and flexible platform for building diverse applications, it presents security issues when running third-party code via npm packages. When using external packages, you must trust the package authors, as Node.js provides access to everything on the computer.
Although Node.js isn’t inherently secure, Deno is designed to be secure by default. That is, you need to grant permission to the main script to access computer resources such as file reading and writing or network requests. By default, if you don’t grant permission when invoking the command line interface, Deno will prompt you to allow the script to access the resource.
Let’s see it in action by executing the previously mentioned fetch script without providing network access from the command line. When the script tries to make a network request, the Deno runtime prompts us for permission to perform the request from the specific host. If we decline, the network request fails, as seen in the script output. If we agree, the script can successfully make the network request and retrieve data from the host.
$ deno run http-2.js
┌ ⚠️ Deno requests net access to "jsonplaceholder.typicode.com".
├ Requested by `fetch()` API.
├ Run again with --allow-net to bypass this prompt.
└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions) > n
❌ Denied net access to "jsonplaceholder.typicode.com".
Error: Requires net access to "jsonplaceholder.typicode.com", run again with the --allow-net flag
$ deno run http-2.js
┌ ⚠️ Deno requests net access to "jsonplaceholder.typicode.com".
├ Requested by `fetch()` API.
├ Run again with --allow-net to bypass this prompt.
└ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions) > y
✅ Granted net access to "jsonplaceholder.typicode.com".
Task #1 => delectus aut autem
As we can see, with Deno, it’s easier to verify that untrusted code is doing what it claims to do.
Your Thoughts
Based on these reasons, I find that Deno has an edge over Node.js. Deno natively supports TypeScript, prioritizes security, simplifies user experience, and follows web standards. What’s your perspective? Do you find Node.js superior in these or any other aspects?