If you are familiar with NodeJS, you may be interested in learning about Deno, a new JavaScript runtime built by Ryan Dahl, the creator of Node.js. Deno is built on the V8 JavaScript engine but was built using Rust instead of C++, and one of its main goals is to bring server-side JavaScript closer to browser JavaScript. In this article, we will introduce you to Deno and its features.
Importing Packages
Deno uses URLs to import packages, and it caches them locally on the first run, similar to npm install. For example, to import the Oak web framework, you can use the following code:
import { Application } from "https://deno.land/x/oak/mod.ts";
Deno doesn't need to
npm install
packages. A similar effect can be achieved withdeno cache --node-modules-dir <glob>
Bundling and Compiling
Deno has built-in tools for bundling and compiling TypeScript code. To bundle your code, you can use the following command:
# deno bundle <in> <out>
$ deno bundle app.ts app.bundle.js
To compile your TypeScript code, you can use the following command: This will build a self contained executable.
# deno compile <flags> <input>
$ deno compile --allow-net app.ts
Both bundling and compiling to standalone executable is a built-in feature of Deno.
Configuring Deno
Deno uses deno.json
to specify configuration options for your application.
This file is similar to package.json
's scripts
section in NodeJS. You can
use it to specify command-line options like this:
{
"scripts": {
"start": "deno run --allow-net app.ts"
}
}
The documentation has detailed sections on:
- Configure the TypeScript compiler options
- linting
- formatting
- imports (alternative to import_map)
- locking
- nodeModulesDir
Managing dependencies
There are two main ways of collecting and managing dependencies. Either by
putting them all in deps.ts
or use an import_map
either through an
import_map.json
or deno.json
's imports
property
deps.ts
By convention in Deno land we use a file called deps.ts
to manage
dependencies. This file is similar to package.json
in NodeJS and contains all
the dependencies required by your application. You can import dependencies from
deps.ts
like this:
deps.ts
export { Application } from "https://deno.land/x/oak@v12.6.0/mod.ts";
main.ts
import { Application } from "./deps.ts";
deno.json or import_map.json
Deno uses import_map.json
to map URLs to local file paths. This file is
similar to package.json
's dependencies
section in NodeJS. You can use it to
map URLs to local files like this:
Using import_map.json
import_map.json
{
"imports": {
"oak": "https://deno.land/x/oak/mod.ts"
}
}
deno.json
{
...
"importMap": "./import_map.json"
}
Using only deno.json
deno.json
{
"imports": {
"oak": "https://deno.land/x/oak/mod.ts"
}
}
Now importing oak
works like you're used to in NodeJS, with simply using a
naked specifier and not a full blown URL. This is desirable when you have to
import a package in multiple places or migrating a NodeJS project to Deno.
Pro tip: If you have a
package.json
in your project, deno can detect it and us it as an import map.
import { Application } from "oak";
Built-in Tools
Deno comes with several built-in tools, including a test runner, a code formatter, and a linter. These tools can be used to improve the quality of your code and make development easier.
Web Standard Compatibility
Deno aims to have the same APIs on the server that you would use in the browser. This means that you can use web standards like the fetch API on the server, making it easier to write code that works in both environments.
Locking and Vendoring
Deno does not have a built-in package manager like npm, but it does have a
mechanism for locking and vendoring dependencies. You can use the --lock
and
--lock-write
options to lock your dependencies, and the --import-map
option
to vendor them.
NPM Support
Deno does support npm packages with the special npm:
modifier import or
through esm transpilers like esm.sh
;
Node.js | Deno |
---|---|
node file.js | deno run file.js |
ts-node file.ts | deno run file.ts |
node -e | deno eval |
npm i -g | deno install |
npm i / npm install | n/a ¹ |
npm run | deno task |
eslint | deno lint |
prettier | deno fmt |
package.json | deno.json / deno.jsonc / import_map.json |
tsc | deno check ² |
typedoc | deno doc |
jest / ava / mocha / tap / etc | deno test |
nodemon | deno run/lint/test --watch |
nexe / pkg | deno compile |
npm explain | deno info |
nvm / n / fnm | deno upgrade |
tsserver | deno lsp |
nyc / c8 / istanbul | deno coverage |
benchmarks | deno bench |
¹ Deno does not have a direct equivalent for installing local packages or dependencies.
² deno check
is similar to TypeScript's tsc
but not a one-to-one
replacement.
Conclusion
In conclusion, Deno is a new JavaScript runtime that aims to bring server-side JavaScript closer to browser JavaScript. It has several features that make it a compelling alternative to NodeJS, including built-in tools, web standard compatibility, and a mechanism for locking and vendoring dependencies. While Deno is still relatively new, it is worth exploring for your next project.