Book Image

Deno Web Development

By : Alexandre Portela dos Santos
Book Image

Deno Web Development

By: Alexandre Portela dos Santos

Overview of this book

Deno is a JavaScript and TypeScript runtime with secure defaults and a great developer experience. With Deno Web Development, you'll learn all about Deno's primitives, its principles, and how you can use them to build real-world applications. The book is divided into three main sections: an introduction to Deno, building an API from scratch, and testing and deploying a Deno application. The book starts by getting you up to speed with Deno's runtime and the reason why it was developed. You'll explore some of the concepts introduced by Node, why many of them transitioned into Deno, and why new features were introduced. After understanding Deno and why it was created, you will start to experiment with Deno, exploring the toolchain and writing simple scripts and CLI applications. As you progress to the second section, you will create a simple web application and then add more features to it. This application will evolve from a simple 'hello world' API to a web application connected to the database, with users, authentication, and a JavaScript client. In the third section, the book will take you through topics such as dependency management, configuration and testing, finishing with an application deployed in a cloud environment. By the end of this web development book, you will become comfortable with using Deno to create, maintain, and deploy secure and reliable web applications.
Table of Contents (15 chapters)
1
Section 1: Getting Familiar with Deno
5
Section 2: Building an Application
10
Section 3: Testing and Deploying

Why Deno?

Many things have changed since Node.js was created. More than a decade has passed; JavaScript has evolved, as well as the software infrastructure community. Languages such as Rust and golang were born and were very important developments in the software community. These languages made it much easier to produce native machine code while providing a strict and reliable environment for developers to work on.

However, this strictness comes at the cost of productivity. Not that developers don't feel productive writing those languages, because they do, but you can easily argue that productivity is a subject where dynamic languages clearly shine.

The ease and speed of developing dynamic languages makes them a very strong contestant when it comes to scripting and prototyping. And when it comes to thinking about dynamic languages, JavaScript directly comes to mind.

JavaScript is the most used dynamic language and runs in every device with a web browser. Due to its heavy usage and giant community, many efforts have been put into optimizing it. The creation of organizations such as ECMA International has ensured that the language evolves stably and carefully.

As we saw in the previous section, Node.js played a very successful role in bringing JavaScript to the server, opening the door to a huge amount of different use cases. It's currently used for many different tasks, including web development tooling, creating web servers, and scripting, among many others. At the time of its creation, and to enable such use cases, Node.js had to invent concepts for JavaScript that didn't exist before. Later, these concepts were discusses by the standards' organizations and added to the language differently, making parts of Node.js incompatible with its mother language, ECMAScript. A decade has passed, and ECMAScript has evolved, as well as the ecosystem around it.

CommonJS modules are no longer the standard; JavaScript has ES modules now. TypedArrays are now a thing, and finally, JavaScript can directly handle binary data. Promises and async/await are the go-to way with asynchronous operations.

These features are available on Node.js, but they must coexist with the non-standard features that were created back in 2009 that still need to be maintained. These features, and the large number of users that Node.js has, made it difficult and slow to evolve the system.

To solve some of these problems, and to keep up with the evolution of the JavaScript language, many community projects were created. These projects made it possible for us to use the latest features of the language but added things such as a build system to many Node.js projects, heavily complicating them. Quoting Dahl, it "took away from the fun of dynamic language scripting."

More than 10 years of heavy usage also made it clear that some of the runtime's fundamental constructs needed improvement. A lack of a security sandbox was one of the major issues. At the time Node.js was created, it was possible for JavaScript to access the "outside world" by creating bindings in V8 – the JavaScript engine behind it. Even though these bindings enabled I/O features such as reading from the filesystem accessing the network, they also broke the purpose of the JavaScript sandbox. This decision made it really hard to let the developer control what a Node.js script has access to. In its current state, for instance, there's nothing preventing a third-party package in a Node.js script to read all the files the user has access to, among performing other nefarious actions.

A decade later, Ryan Dahl and the team behind Deno were missing a fun and productive scripting environment that could be used for a wide range of tasks. The team also felt like the JavaScript landscape has changed enough that it was worthwhile simplifying, and thus they decided to create Deno.

Presenting Deno

"Deno is a simple, modern, and secure runtime for JavaScript and TypeScript that uses V8 and is built into Rust." – https://deno.land/

Deno's name was constructed by inverting the syllables of its ancestor's name, no-de, de-no. With a lot of lessons learned from its ancestor, Deno presents the following as its main features:

  • Secure by default
  • First-class TypeScript support
  • A single executable file
  • Provides fundamental tools to write applications
  • Complete and audited standard library
  • Compatibility with ECMAScript and browser environments

Deno is secure by default, and it was created like that by design. It ultimately leverages the V8 sandbox and provides a strict permission model that enables developers to finely control what the code has access to.

TypeScript is also first-class supported, meaning developers can choose to use TypeScript without any extra configuration. All the Deno APIs are also written in TypeScript and thus have correct and precise types and documentation. The same is true for the standard library.

Deno ships a single executable with all the fundamental tools needed to write applications; it will always be that way. The team makes an effort to keep the executable small (~15 MB) so that we can use it in various situations and environments, from simple scripts to full-fledged applications.

More than just executing code, the Deno binary provides a complete set of developer utilities, namely a linter, a formatter, and a test runner.

Golang's carefully polished standard library inspired Deno's standard library. It is deliberately bigger and more complete compared to Node.js'. This decision was made to address the enormous dependency trees that used to occur in some Node.js projects. Deno's core team believes that, by providing a stable and complete standard library, it can help address this problem. By removing the need to create third-party packages to handle common use cases the platform provides by default, it aims to diminish the need to use loads of third-party packages.

To keep compatibility with ES6 and browsers, Deno made efforts to mimic browser APIs. Things such as performing HTTP requests, dealing with URLs, or encoding text, among others, can be done by using the same APIs you'd use in a browser. A deliberate effort was made by the Deno team to keep these APIs in sync with the browser.

Aiming to offer the best of three worlds, Deno provides the prototype-ability and developer experience of JavaScript, the type-safety and security offered by Typescript, and Rust's performance and simplicity.

Ideally, as Dahl also mentioned in one of his talks, code would follow the following flow in the path from prototype to production: developers can start writing JavaScript, migrate to TypeScript, and end up with Rust code.

At the time of writing, is it only possible to run JavaScript and TypeScript. Rust is only available via a (still unstable) plugin API that might become stable in a not-so-distant future.

A web browser for command-line scripts

As time passed, the Node.js module system evolved into something that is now overly complex and painful to maintain. It takes into consideration edge cases such as importing folders, searching for dependencies, importing relative files, searching for index.js, third-party packages, and reading the package.json file, among others.

It also got heavily coupled with npm, the Node Package Manager, which was initially part of Node.js itself but separated in 2014.

Having a centralized package manager is not very webby, to use Dahl's words. The fact that millions of applications depend on a single registry to survive is a liability.

Deno solves this problem by using URLs. It takes an approach that's very similar to a browser, only requiring an absolute URL to a file to execute or import code. This absolute URL can be local, remote, or HTTP-based and includes the following file extension:

import { serve } from 'https://deno.land/[email protected]/http/server.ts'

The preceding code happens to be the same code you would write on a browser inside a <script> tag if you want to require an ES module.

In regard to installation and offline usage, Deno ensures that users don't have to worry about that by using a local cache. When the program runs, it installs all the required dependencies, removing the need for an installation step. We'll dive into this later in more depth later, in Chapter 2, The Toolchain.

Now that we are comfortable with what Deno is and the problems it solves, we're in good shape to go beyond the surface. By knowing what is happening behind the scenes, we can get a better comprehension of Deno itself.

In the next section, we'll explore technologies that support Deno and how they connect.