It’s the beginning of October 2024 and time for a new version of Deno. We already looked at Deno in a Techup with Deno some time ago. But so far, Deno hasn’t really made the big breakthrough. However, this should change with the new version. That’s why we’re taking a look at what’s changed today.
If you look at the announcement of Deno 2, you immediately realize that its goal is to simplify web development. And that, although everything is becoming more and more complex and therefore more complicated. Especially we developers notice this more and more often, because before you can even start with the actual work, complex configurations have to be made. This is exactly where Deno comes in: It offers a modern, all-in-one, zero-config toolchain for JavaScript and TypeScript development.
With native TypeScript support, built-in web standards like Promises, fetch
and ES Modules, and a comprehensive toolbox (including formatter, linter, type checker, and test framework), Deno 2 focuses on making the tool even more scalable and seamlessly integrating it into the existing JavaScript infrastructure - without sacrificing the simplicity and security that Deno users appreciate.
Review
But now again as a small reminder, what was the topic in the last Techup, because that was two years ago.
Deno is a runtime for JavaScript and TypeScript. It was announced in 2018 by Ryan Dahl, the inventor of Node.js, and released in version 1.0 in 2020. His goal was to fix design flaws in Node.js with Deno.
One of the biggest problems was the use of Async/Await, as Promises were not introduced until much later. Security also played no role in the early days of Node.js. The centralized, privately controlled npm repository led to potentially insecure dependencies, and the node_modules folder had to be recreated for each project, resulting in large amounts of data. The outdated CommonJS module system was confusing compared to ES Modules and could no longer be removed due to its widespread use.
Deno solved these problems through various improvements by including built-in tools such as package manager, compiler, formatter and linter (“Batteries Included”). Security was implemented according to the motto “Secure by Default” by only granting permissions to explicitly allowed accesses. Deno supports TypeScript natively without additional configuration and uses tested standard modules without external dependencies, which increases security. It relies on ES Modules and uses a decentralized module system where modules are imported via URLs. Top-Level Await simplifies asynchronous programming because await
no longer needs to be wrapped in an async
function. In addition, web APIs such as fetch
can be used directly without additional packages.
The general architecture has also been modernized by writing Deno in Rust and JavaScript. Tokio is used here instead of libuv.
Deno supports TypeScript natively without additional configuration and uses tested standard modules without external dependencies, which increases security. It relies on ES Modules and uses a decentralized module system where modules are imported via URLs. Top-Level Await simplifies asynchronous programming because await
no longer needs to be wrapped in an async
function. In addition, web APIs such as fetch
can be used directly without additional packages.
Improvement of existing features
Before we look at the exciting new topics, here is a short list of improvements from the existing Deno functionality
deno fmt
can now also format HTML, CSS and YAMLdeno lint
now includes Node-specific rules and quick fixesdeno test
now supports running tests written withnode:test
deno task
can now runpackage.json
scripts- The HTML output of
deno doc
has an improved design and a better search function deno compile
now supports code signing and icons on Windowsdeno serve
can run HTTP servers in parallel across multiple coresdeno init
can now pre-configure libraries or serversdeno jupyter
now supports the output of images, graphics and HTMLdeno bench
supports critical sections for more accurate measurementsdeno coverage
can now output reports in HTML format
New Features
Backwards-compatible
One of the new features is full backwards compatibility with Node and npm. Previously, it was basically already possible to use Deno as an alternative to Node.js, but in everyday life it was very difficult to fully integrate Deno into existing projects. Many tools that are standard in the Node world - such as Prettier for formatting code or npm scripts for automating tasks - could not be used seamlessly with Deno.
That has fundamentally changed with Deno 2. The new version makes it possible to seamlessly integrate Deno into existing Node projects and gradually leverage its modern, all-in-one toolchain without having to abandon the familiar infrastructure. Deno now understands the structures of a Node project, such as the package.json
, npm workspaces, and node_modules
, and allows you to use familiar tools such as deno fmt
or deno install
directly. This allows dependencies to be installed or code formatted at lightning speed without relying on external tools like Prettier.
This also includes the direct use of npm
. The good thing is that you no longer need the usual package.json
file and the node_modules
folder, which saves you a lot of overhead. Thanks to the npm:
specifier, this can now be used directly in the code or in a deno.json
file.
A simpler example using direct import:
|
|
The special thing: Deno installs the package in the global cache, so neither a separate configuration file nor the well-known node_modules
folder is required. This way you can write programs with npm
dependencies in a single file.
Or you should use a deno.json file:
|
|
And can then be used directly in the class as usual:
|
|
Deno 2 provides access to over 2 million npm modules, including more complex packages like gRPC, Prisma, ssh2, or duckdb. Even advanced features like native Node API addons are supported, making Deno an extremely flexible choice for modern JavaScript and TypeScript projects. This means that modern JavaScript frameworks such as Next.js, Astro, Remix, Angular or SvelteKit can now also be used without any problems.
Here is an example of how to create a nextJS app directly using deno:
|
|
This then results in the following familiar structure:
|
|
Package Manager
In addition, the range of functions has been expanded, as Deno can now also be used as a powerful package manager. There are mainly three standard commands.
First there is deno install
, which allows you to quickly install and manage dependencies. It doesn’t matter whether a project uses a package.json
or not - Deno adapts flexibly. If a package.json
exists, a node_modules
folder will be created during the execution of deno install
- just like in a classic JavaScript project. In addition, the speed of Deno has been significantly improved compared to other package managers. With a so-called “cold cache” - i.e. when dependencies have to be downloaded for the first time - Deno is 15% faster than npm. With a “warm cache”, when already installed packages are used, Deno is even 90% faster. It has also been announced that there will be further improvements in this area.
With deno add
, new packages can easily be added to a package.json
or deno.json
. The current version of the package is automatically installed and the dependency is noted in the corresponding configuration file. This makes it easier to manage dependencies in larger projects and ensures that all required modules are cleanly documented.
Similarly, deno remove
allows you to remove packages from the package.json
or deno.json
. The package is not only deleted from the configuration file, but also from the node_modules
folder or the global cache, freeing the project from unnecessary dependencies.
JSR
Before we move on to the next new feature, let’s take a quick look at what JSR is all about. JSR was also introduced by Deno in March 2024. It is a new package repository for JavaScript and TypeScript. The goal is, of course, to eliminate the weaknesses of npm.
Why this is even an issue is due to the constant development in the field of JavaScript.
A lot has changed in the JavaScript world since 2009: The standard for modularization has shifted from CommonJS to ES modules (ESM), which enables more modern and efficient handling of modules. In addition, TypeScript has gained enormous popularity and offers developers the opportunity to write JavaScript with static typing, which improves code quality and maintainability. In addition to Node.js, new runtimes such as Deno, Bun and Cloudflare Workers have emerged that support innovative features and standards and further enrich the diversity of JavaScript development.
The most important points:
-
Optimized for TypeScript: Developers can publish TypeScript code directly without prior transpilation.
-
Supports ES Modules Only: Encourages the use of the current JavaScript module standard.
-
Compatible with different runtimes: Works with Deno, Node.js, Bun, Cloudflare Workers and others.
-
Free and Open Source: JSR is available under the MIT license and invites community participation.
Digression — ESM vs CJS
Here is a small excursus to show again the advantages of using ESModules.
Syntax and readability
The ESM syntax is clearer and easier to read because import
and export
are native, as opposed to the function syntax of require()
and module.exports
.
ESModules (ESM):
|
|
CommonJS (CJS):
|
|
Static analysis
With ESM, tools (like Webpack) can load only the functions they need (here add
) and omit unused code (e.g. subtract
), while with CommonJS the entire module is loaded.
ESModules (ESM):
|
|
CommonJS (CJS):
|
|
Asynchronous loading
ESM is supported directly in the browser and can be loaded asynchronously, which is not possible with CommonJS.
ESModules (ESM):
|
|
CommonJS (CJS):
|
|
Module areas (strict mode)
In ESM there is no this
binding at the global level and it automatically runs in strict mode, which reduces error-proneness.
ESModules (ESM):
|
|
CommonJS (CJS):
|
|
Exports as real objects
With ESM, exports are real, shared bindings. Changes in the module are reflected immediately. With CJS, on the other hand, only copies of the values are exported, so changes are not visible.
ESModules (ESM):
|
|
CommonJS (CJS):
|
|
Standard Library — “std”
A lot has also changed in the Deno standard library since the first release 4 years ago. The selected modules are thoroughly tested modules that provide a large number of functions, such as data manipulation, web-related logic and JS-specific functions. This library is also available from JSR and can therefore be used in other projects.
Examples of modules in the Deno standard library and their npm counterparts:
Deno Standard Library Module | Corresponding npm package |
---|---|
@std/testing |
jest |
@std/expect |
chai |
@std/cli |
minimist |
@std/collections |
lodash |
@std/fmt |
chalk |
@std/net |
get-port |
@std/encoding |
rfc4648 |
For a complete list of available packages visit: https://jsr.io/@std.
Private npm registries
This now works the same way as with Node and npm. All you need is a .npmrc file.
Workspaces and monorepos
By using workspaces for individual folders/packages, it is possible to structure the project as a monorepo. To do this, a deno.json
or package.json
file must be created at the top level, which contains the individual workspaces. Each of these workspaces can then have its own deno.json
file.
Initial state after checkout from the example repo
|
|
The definition of the individual workspaces then looks like this at the top level:
|
|
If you now run a deno install
to install all dependencies, a deno.lock and a node_modules folder will be created at the top level.
|
|
LTS
Since Deno has previously released weekly bug fix releases and minor releases every six weeks, it is difficult, especially for larger enterprise companies, to keep up with this rhythm. For this reason, Deno plans to provide an LTS version starting with version 2.1. This LTS channel will receive critical bug fixes for six months.
Deno for Enterprise
For teams that need advanced support, Deno has introduced the Deno for Enterprise program. This offers:
- Prioritized support
- Direct access to Deno engineers
- Guaranteed response times
- Priority for your feature requests
Conclusion
I have to say, after looking at the new version and its features on my own, it looks like it’s greatly increasing the use case for Deno. Especially the integration into existing projects that were previously based on Node.js and npm. By being able to continue using package.json and also deno.json, a smooth transition to deno can be achieved.
But I will definitely try to incorporate it into existing projects in the near future to see if it really works as planned. The hurdles that are otherwise common when introducing new technologies are significantly lower thanks to this seamless integration. Of course, it depends on the respective project team whether Deno is completely replaced or introduced step by step.
I find the introduction of LTS versions to be excellent, especially for enterprise customers. In large companies, you can’t always switch to the latest versions immediately, so LTS support provides the necessary stability and security. And in this way it also makes it possible to actually use Deno in more projects.
Overall, I am very optimistic about the future of Deno. The improvements in Deno 2 make it an even more attractive option for modern JavaScript and TypeScript projects. I look forward to taking full advantage of the new version and am excited to see how Deno evolves.
This techup has been translated automatically by Gemini