Source: https://www.youtube.com/watch?v=d35SlRgVxT8
Deno 2.0, the latest release of Deno, is being hailed as a promising alternative to Node.js, especially for developers who value a streamlined JavaScript and TypeScript runtime. This article takes a closer look at what Deno 2.0 brings to the table, including its setup, usage, and compatibility with existing tooling
008: Deno2 Introduction
As a Node.js replacement, Deno 2.0 aims to provide a more cohesive development experience by simplifying package management and removing the need for complex toolchains like linters and formatters. This article explores Deno 2.0's features and compares them with other runtime environments, including Bun and Node.js, offering insights into its pros, cons, and potential as a new standard for developers.
The Problem
Node.js is a powerful and well-supported runtime, especially with its extensive ecosystem of packages and frameworks. However, there are moments when it can feel like a patched-together solution, held up by various tools and configurations (and I say this as someone with a PHP background). While no runtime or framework is perfect, the process of updating my
package.json
or resolving conflicting configurations between TSConfig and ESLint can sometimes feel cumbersome.What is Deno?
Deno is a project developed by the creator of Node.js, aiming to provide a JavaScript and TypeScript runtime that avoids the setup complexities associated with Node.js. With Deno, TypeScript is supported natively, eliminating the need for transpilers. Deno 2.0’s recent release introduces full npm compatibility, a feature that is crucial for Node.js developers looking to transition without losing access to essential npm packages.
Deno 2.0 vs. Bun
Deno 2.0 enters the runtime competition relatively late, as Bun has already established npm and yarn-lock compatibility, making it easy for developers to deploy or run a CI pipeline without direct support for Bun.
How Deno 2.0 Compares
Milad Fahmy compared Node.js 22, Bun.sh, and Deno 2.0, highlighting some unique support features and the maturity of each runtime’s functionalities and ecosystem.
Impressions
As a hands-on person, I decided to test Deno 2.0 on my own Next.js project (the one hosting this blog) to see if it could work as my development runtime. (Did I mention I dislike configuring linters?)
Installation
Installing Deno 2.0 is straightforward. You can find installation commands in their documentation at https://docs.deno.com/runtime/getting_started/installation/. On UNIX-like systems, you simply run:
curl -fsSL https://deno.land/install.sh | sh
I was, however, surprised to find that Deno 2.0 isn’t yet supported on Linux ARM64, which affects my development setup on a Chromebook. Hopefully, this changes soon.
Commands Mapping
- Install packages:
deno install
->bun/npm install
- Add a new package:
deno add [package]
->bun/npm add [package]
- Remove a package:
deno remove [package]
->npm uninstall [package] / bun remove [package]
- Run a command:
deno task [command]
->bun/npm run [command]
- Format code:
deno fmt
->bun/npm run prettier:fix
(prettier) - Lint code:
deno lint
->bun/npm run lint:fix
(eslint)
For a comprehensive list, see: https://docs.deno.com/runtime/fundamentals/node/#node-to-deno-cheatsheet
Migrating Your Project
To start adapting my project, I used:
deno fmt
deno lint
Aligning the rules between
deno.json
and my ESLint/Prettier/TSConfig files took about 30 minutes. For example, Deno 2.0 prefers single quotes, whereas my linters use double quotes, leading to a substantial number of file changes, but these adjustments were manageable.Next, I ran:
deno install
deno task dev
This step revealed some incompatibilities, especially with Webpack, which required adding
node:process
to imports. To resolve this in my next.config.js
, I added:webpack: (config, { isServer }) => {
config.plugins.push(
new webpack.NormalModuleReplacementPlugin(
/^node:/,
(resource) => {
resource.request = resource.request.replace(/^node:/, '');
},
)
);
return config;
},
Deno also appends file extensions to imports (e.g.,
.ts
, .js
), requiring the allowImportingTsExtensions: true
flag in TSConfig for backward compatibility. Other than these minor tweaks, the migration was seamless.Finally, I ran:
deno task build
deno task start
Running my project locally with Deno 2.0 only required minor TypeScript adjustments, and the process felt smoother and more robust.
Problems
Deno 2.0 has some limitations. While it does support GitHub Actions:
My Bun-based CI still outpaces npm by running twice as fast, so I opted to keep it as is for now. Additionally, Deno is not yet supported for Vercel deployments. Although a community Deno runtime exists, but it remains at version 1.x.
Give It a Try
If you’re interested in Deno 2.0, I recommend this tutorial that demonstrates creating, testing, and running an API. It also includes benchmarks comparing Deno 2.0, Node.js, and Bun.
Conclusion
Node.js remains the current standard and won’t be going away anytime soon. While Bun positions itself as an npm alternative, Deno 2.0 seeks to replace Node.js entirely. Each has its advantages, with Bun offering better integration with Node.js tools and support for both CI pipelines and Vercel. But competition drives innovation, and I’m excited to transition my Next.js project fully to TypeScript and Deno 2.0 for local development and, eventually, for CI and deployment as well.
Published: Sunday, Oct 27, 2024, 11:02 AM