Welcome Deno! Does this mean goodbye to Node.js?
What is Deno?
TypeScript out of the box:
Deno offers native support for TypeScript at its 3.9 version. For it to run nothing else needs to be installed, and no compilation step is needed since Deno transpiles the code behind the scenes. It is also possible to run the code with a custom
tsconfig.json file to customize how Deno compiles your code.
Node.js projects have a
package.json file that contains relevant information for your project. It also holds the dependency list that you’ll be using. Deno handles this part in a completely different way. The
package.json file is not used anymore in favor of
ES Modules. In order to use modules in a Deno project, you will need to reference each module with its URL or file path.
When the application is executed for the first time, Deno downloads and caches all modules in a global cache. It is possible to store them in a custom directory using the
$DENO_DIR environment variable. With this approach, Deno decentralizes the modules and your project will not have a large
To keep module versions locked, it is possible to create a lock file with the
Secure by Default:
Deno has some security measures in place to disallow potentially dangerous operations. By default, the code is executed in a secure sandbox, so it is not possible to access the network, file system, or environment unless you explicitly allow it. You can do this by adding flags when running the application. These are enabled by default in Node.js, which makes it insecure in some cases.
As a quick overview of what can be enabled we have the following flags:
# Enable environment access with Deno.env.get deno run --allow-env my-application.ts #Enable high resolution time measurement (used for profiling) deno run --allow-hrtime my-application.ts #Enable network access # This is used in cases where we want to fetch from external servers # or when we want to expose a port from our server deno run --allow-net=https://example.com my-application.ts # Enable plugin usage deno run --allow-plugin my-application.ts # Enable filesystem access # To read a file or directory with Deno.open, or write to a file # or directory with Deno.writeFile deno run --allow-read=awesome.txt my-application.ts deno run --allow-write=awesome.txt my-application.ts # Enable subprocess execution with Deno.run deno run --allow-run my-application.ts # Disable all security checks deno run --allow-all my-application.ts
In Deno, we have some nice tools available out of the box. This means that we don’t need to install any additional libraries for some common development tasks. At a glance, these utilities are:
Debugger: Like Node, Deno supports the V8 Inspector Protocol, which means that it’s possible to debug the program in any client that supports it. This consists mainly of two commands:
From this point, all you have to do is open your client and the program will stop on the first line, allowing you to set up breakpoints where you need to. For VSCode you can add the entry point and arguments to your
launch.json to enable it.
Formatter: In Node.js applications, it’s common to add a linter tool (typically ESLint) with a formatter like Prettier so the code is standardized. Deno has this feature built into it. You can access it by simply running
Bundler: Bundling is a task that is currently done with webpack, gulp or Grunt in Node.js applications. We can use Deno’s bundler when we want to pack a module together with its dependencies and this will generate a single module we can reference from other files. These bundles can also be loaded in the web browser.
<script> tag in our HTML with the
Dependency inspector: We can display a tree structure of our dependencies using the
deno info command, followed by the URL we want to inspect. This is similar to
npm ls in Node
deno info https://deno.land/std/uuid/test.ts local: /Users/foo/Library/Caches/deno/deps/https/deno.land/997789467b3621b5d93c6b18bf8b275f35057b24f934c2508e3d1ef52cd51644 type: TypeScript compiled: /Users/foo/Library/Caches/deno/gen/https/deno.land/std/uuid/test.ts.js map: /Users/foo/Library/Caches/deno/gen/https/deno.land/std/uuid/test.ts.js.map deps: https://deno.land/std/uuid/test.ts ├─┬ https://deno.land/std/uuid/tests/isNil.ts │ ├─┬ https://deno.land/std/testing/asserts.ts │ │ ├── https://deno.land/std/fmt/colors.ts │ │ └── https://deno.land/std/testing/diff.ts │ └─┬ https://deno.land/std/uuid/mod.ts │ ├─┬ https://deno.land/std/uuid/v1.ts . . .
All async actions in Deno return a promise. This is interesting because the
await keyword is supported on the top level and there is no need to define the function with the
async keyword. This approach allows us to write more readable code when working with asynchronism.
Deno supports promises out of the box. In the first example, the
await keyword waits until
Deno.open is resolved and its result is stored in the
file variable. In the second example,
server is an async iterator and the
for await keywords are used to iterate them, each item will be a new incoming request.
Deno has incredible features, but there are two points that I think can be improved: - The permission flags could be handled in a different way like using a file that allows us to set the flags. If your code needs almost all the permissions you will have to use a long command. However, this is not a big issue on itself. - About the dependencies, NodeJS has a better project organization and the
lock file is generated automatically. With Deno your dependencies will be placed in one directory, and to lock the dependencies you need to run an additional command. This might not be a good developer experience, but the community is working on some alternatives to change this.
Another point I would like to mention is regarding the examples and tutorials. On the NodeJS side, you can find a lot of examples/tutorials of any library or functionality you may need, while with Deno there are few examples/tutorials. But it will increase in the future for sure.
In this link you will find a small example using Deno and Typescript that shows how to create routes with the
oak module, submit data from a form and generate a CSV file with the provided data.
Deno is a good alternative for increasing security that allows us to use TypeScript without extra configurations or tooling. It’s really nice to write code and see that all the magic occurs behind the scenes. Now there are no more excuses to not use TypeScript.
Having a stable release 1.0, Deno is not yet considered production-ready given that it has some features in the draft phase and needs more time to mature. Right now isn’t the time to say goodbye to Node.js, however, in the next couple of years we will see Deno mature and become production ready. I hope that development teams give this tool a chance and that they share their experiences soon.