Deno in 2024
In 2024, the Deno team made significant strides towards our vision of simplifying programming. We launched the highly anticipated Deno 2, which provides backwards compatibility with Node and npm, adds dependency management to the toolchain, and expanded flexibility with monorepo and workspace support. Here’s a summary of notable technical improvements in 2024:
- You can now run Node applications with Deno 2,
which offers native
package.json
andnode_modules
support, as well as improved compatibility with CommonJS. These improvements also unlock the ability to incrementally adopt pieces of Deno’s all-in-one toolchain. - Deno’s npm compatibility was significantly improved.
Now you can use packages like
@grpc/grpc-js
,playwright
,@google-cloud
,mysql2
,pglite
,ssh2
, and much more with Deno. - This year we introduced JSR, a modern, open sourced JavaScript registry, which has native TypeScript support (you can publish modules as TypeScript source), can handle module loading across runtimes and environments, auto-generates documentation from JSDoc-style comments, and can be used with any npm compatible package manager. Read more.
- Deno’s built-in toolchain now
includes an npm and JSR package manager with the addition of these subcommands
deno install
,deno add
,deno remove
, anddeno outdated
. Deno can install dependencies from either npm or JSR, and performs 15% faster than npm with a cold cache and 90% faster with a hot cache. - We’ve made
Deno.serve()
faster by 8-15%, added the ability to write servers declaratively, and introduceddeno serve
subcommand, which supports multi-threaded servers with the--parallel
flag. - Code signing and asset bundling are now supported in
deno compile
, to make compiling self-contained cross-platform executables from JavaScript even easier. We’ve also roughly halved the size ofdeno compile
output in 2024. - After 5 years of development,
we stabilized
rusty_v8
, a Rust crate that provides high-quality, zero-overhead Rust bindings to V8’s C++ API, and which runs at the core of Deno. If you’re interested in creating custom JavaScript runtimes or embedding JavaScript in Rust applications, be sure to explore its API. - The Deno standard library, a collection of heavily audited utility modules ranging from data manipulation, web-related logic, JavaScript-specific functionalities, and more, was stabilized at version 1.0. It’s available on JSR and can be used in other runtimes and environments, like the browser. Read more.
- The Deno project crossed 100k stars on GitHub! Thank you all for your support.
Let’s take a deeper look into these updates below.
Backwards compatibility with Node and npm
In 2022, our survey responses indicated the importance of being able to use npm packages with Deno. Two years of diligent work later, with the release of Deno 2, we’re thrilled to announce that Deno provides backwards compatibility with Node and npm.
Some key updates to Deno to enable backwards compatibility include understanding
package.json
, removing global variable window
and adding process
, making
the
“bring your own node modules”
functionality the default, and dozens of bug fixes to node:
built-ins and
more. With Deno 2, not only can you run existing Node projects in Deno, but also
you can import and use npm packages, such as playwright
, prisma
, sqlite3
,
duckdb
, and
gRPC
. On top of
that, Deno 2 supports JavaScript frameworks such as Next.js, Astro, Remix, Qwik,
Solid, and much more.
Though we firmly believe ES modules are the future of JavaScript, many legacy
projects and libraries rely on CommonJS. In 2024, we have
improved our CommonJS support.
Deno can run and import CommonJS files with the .cjs
extension, as well as
offering more descriptive errors when dealing with CommonJS issues.
Finally, to allow for more flexibility in your Deno project, we’ve added
monorepo and workspace support.
Deno workspaces also understands npm workspaces, meaning you can create a hybrid
Deno-npm monorepo with members having either a package.json
or deno.json
.
You can even publish workspace members to JSR with deno publish
without
needing to manually figure out what order to publish them (see the
Deno Standard Library as an example).
Built-in, performant, dependency management
As of Deno 2, Deno comes with a package manager with the addition of these new
subcommands: deno install
, deno add
, and deno remove
. These subcommands
will be familiar if you’ve used npm, but they are much faster: deno install
is
15% faster than npm with a cold cache and 90% faster with a hot cache.
These package management commands can pull/remove packages from either npm or
JSR based on the provided specifier or if the package was found in
package.json
or deno.json
.
To broaden support for npm packages that require executing pre or post-install
scripts, we’ve also added
support for npm lifecycle scripts with the new flag --allow-scripts
:
deno install --allow-scripts=npm:duckdb
Finally, to make it easier to share internal modules in a larger development
team, we’ve added
private npm registry support.
These work the exact same way as they do in Node and npm: with an .npmrc
file:
// .npmrc
@mycompany:registry=http://mycompany.com:8111/
//mycompany.com:8111/:_auth=secretToken
JSR: a modern, open source JavaScript registry
This year, we introduced a new JavaScript registry, JSR. It supports TypeScript natively (you can publish modules as source), handles module loading across runtimes and environments, auto-generates documentation from JSDoc-style comments, and can be used with npm/npx-like systems.
Since TypeScript source can be directly uploaded to JSR, it has a deep understanding of the code. This enables a smoother, seamless developer experience for both publishing and consuming modules. To learn more about all that goes under the hood, read our post on how we architected JSR.
Publishing modules to JSR is very straightforward with deno publish
, and you
can even quickly scaffold a JSR module with deno init --lib
.
✅ Project initialized
Run these commands to get started
# Run the tests
deno test
# Run the tests and watch for file changes
deno task dev
# Publish to JSR (dry run)
deno publish --dry-run
Though the Deno team built JSR, it is intended for the larger JavaScript community. We’re currently working towards building an open governing body for JSR. If you’re interested and want to learn more, check out the JSR discord and join one of our bi-weekly office hours, where we answer community questions and share the JSR roadmap.
Faster, smaller, and simpler cross-platform compiled binaries from JavaScript
Since Deno v1.6, deno compile
has enabled developers to turn JavaScript and
TypeScript programs into single, standalone binaries that run on all major
platforms — no dependencies, no additional installs. This means streamlined
deployment and faster startups. And unlike
Node’s 8-step compilation process,
deno compile
is a single command.
This past year,
we have made major improvements
to deno compile
, such as
slimming down the compiled binary by up to 50%,
adding code signing for software verification, Windows icon support, and
asset bundling.
In addition, programs created with deno compile
can also use
V8 code caching for even faster startup time.
With these updates, you can now compile complete applications
like HTML/JS/CSS games into native desktop binaries.
To demonstrate the performance boost from using deno compile
, here’s an
example of compiling npm
:
deno compile -A npm:npm
In our observations,
Deno-compiled npm
binary ran ~1.9x faster than regular npm
:
# hyperfine "./npm -v" "npm -v"
Benchmark 1: ./npm -v
Time (mean ± σ): 40.1 ms ± 2.0 ms [User: 37.7 ms, System: 5.3 ms]
Range (min … max): 38.9 ms … 51.8 ms 71 runs
Benchmark 2: npm -v
Time (mean ± σ): 75.2 ms ± 7.6 ms [User: 59.1 ms, System: 9.0 ms]
Range (min … max): 69.2 ms … 105.0 ms 40 runs
Summary
./npm -v ran
1.87 ± 0.21 times faster than npm -v
We will continue to iterate and improve on deno compile
, such as the ability
to support compiling full stack frameworks, and more.
deno serve
Faster, simpler web servers with Building web servers is a common use case for Deno, and last year we’ve made
notable improvements in both its performance and usability. We re-worked
the Deno.serve()
API to make it faster by 8-15%.
Writing servers in Deno is easier, too. We’ve also added
the command deno serve
to allow you to write servers declaratively:
export default {
fetch(request) {
return new Response("Hello world");
},
};
$ deno serve server.ts
deno serve: Listening on http://localhost:8000/
$ curl http://localhost:8000/
Hello world
deno serve
also supports multi-threaded servers with the --parallel
flag,
which enables automatic load-balancing across multiple CPU cores with the same
ease-of-use.
You can
kickstart a new server in seconds with deno init --serve
option. Deno also added the ability to
typecheck your server entrypoint file with satisfies Deno.ServeDefaultExport
.
Deno performs great on AWS Lambda
Deno is committed to building the fastest, most performant JavaScript and TypeScript runtime, and last year we made significant strides towards that. We’ve improved startup time by adding V8 code caching and warming up bootstrap initialization during snapshot time.
We’ve also made significant performance improvements in Deno when in serverless
environments, where Deno is commonly used in production. Deno added
a Write-Ahead Logging (WAL) journal for SQLite databases in DENO_DIR
,
improving code caching, startup time, and cold starts. To compare performance in
serverless contexts, we published
a cold starts benchmark on JavaScript runtimes on AWS Lambda,
which includes our methodology, as well as a few tips to maximize performance.
There were many other improvements to the overall Deno performance story from last year. And though benchmarks can never reveal the full story, they can provide insight into where a runtime excels. Here are some benchmarks from the 2.0 release that can hopefully provide a better idea.
Temporal API and Wasm imports
The Temporal
API, designed the
address the limitations and complexities of the Date
object in JavaScript, is
being actively implemented in all major JavaScript engines. You can try it out
in Deno already
with the --unstable-temporal
flag.
While WebAssembly (”Wasm”) support had always been available in Deno, our 2.1 release promotes Wasm support to first-class, making importing Wasm modules as trivial as importing any other module or file:
// Now in Deno 2.1
import { add } from "./add.wasm";
console.log(add(1, 2));
// $ deno main.ts
// 3
Loading Wasm modules is now even more performant in Deno, as they’re part of the “module graph”, which can be analyzed and cached for faster use. Not only that, but Deno understands exporting Wasm modules and can type check their use in your code base.
As more and more Wasm is used on the web to improve application performance in the browser, we’ll continue to work towards making using Wasm with Deno as easy and fast as possible.
Do more with deno.json
Programming should be simple, which is why we built Deno to be zero config with
sane defaults. However, we acknowledge that larger projects often require more
sophisticated setups, so we’ve continuously improved our optional deno.json
configuration file to meet these needs without sacrificing ease-of-use:
- More flexible
tasks
: Yourdeno task
now can includenpm
commands, scripts using shebang, and can be written as objects with informative descriptions and dependencies. When using dependencies,deno task
will run tasks in parallel wherever possible and handle cycles in dependencies to ensure infinite loops are avoided.deno task
can also runpackage.json
scripts. - Enhanced formatting options:
deno fmt
now supports formatting more files, such as HTML, CSS, YAML, Astro, Angular, Svelte, Vue, and more. - Simpler imports: Deno now pre-processes the
imports
field to support a simpler syntax for specifying dependencies with subpath exports.
These improvements help make Deno not only powerful and flexible for large-scale applications, but also simple and accessible for smaller projects.
Deno Standard library, stabilized
Over 4 years, 151 releases, and 4k commits later, the Deno Standard Library is finally stabilized. This collection of 40+, closely audited, utility modules cover a wide gamut of uses in JavaScript, the web, and general data manipulation. The best part is that this library can be used across all JavaScript runtimes and environments like the browser.
To give you a sense of what kinds of modules are available in the Deno Standard Library, here is a partial list of the Standard Library modules and their equivalent in npm:
Deno Standard Library module | 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.
Notable open source Rust crates
Building Deno means touching a wide range of open source projects that we contribute to in order to expand Deno’s features and optimize performance. Here are some Rust crates that developers may find useful independently of Deno itself:
rusty_v8
: This library provides high-quality, zero-overhead Rust bindings to V8’s C++ API. Since we initially released it five years ago, it has seen nearly 150 releases and over 3.1 million downloads on crates.io. Last year, we announced thatrusty_v8
is stable and production-ready.deno_semver
: This Rust crate provides utilities for parsing, comparing, validating, and manipulating semantic versioning (semver) strings used by npm and JSR packages.deno_npm
: This crate is an npm client and serves as bridge between Deno and the npm package ecosystem. This library resolves npm modules in the same way Node.js does, so it’s useful if you’re writing Rust and want to interoperate with the npm ecosystem.deno-vite-plugin
: This Deno Vite plugin enables Deno resolution within Vite, which allows you to use Deno with Vite, as well as importing libraries from JSR and HTTP within Vite.deno_cache_dir
: This TypeScript module provides access to the Deno cache with the same logic of the Deno CLI. Several other Deno tools, such asdeno_graph
,deno_doc
,dnt
, anddeno_emit
, rely on this module to access and populate the cache in the same way as the Deno CLI.
Fresh, Deno Deploy, Subhosting
While we marked a significant milestone with the launch of Deno 2, we continued to operate and iterate our serverless compute platform, Deno Deploy, the simplest way to run arbitrary JavaScript/TypeScript in the cloud.
We’ve given Deno Deploy users an improved onboarding flow with new tutorials that show how easy it is to get started with Deno’s cloud primitives, as well as a streamlined project creation flow that auto-detects frameworks and provides more transparency into the build and deployment steps. We also got Next.js to work on Deno Deploy!
We’ve also given users more flexibility in how they use Deno Deploy.
We released deployctl
, the CLI for Deno
Deploy that lets users create, manage, and observe your deployments from the
terminal. The Web Cache API
support
also grants users fine tuned control over the performance of their deployments.
Also, we’ve implemented
safeguards over cloud billing with new spending limits.
Our enterprise product, Deno Subhosting, continued to see improvements over the past year. We’ve added support for programmatically managing custom domains and subdomains and configuring data backups. If you’d like to learn more about how your product can safely run your users’ untrusted code without months of engineering effort, please get in touch.
Finally, we’re continuing to iterate on our next generation, islands-based full stack web framework, Fresh, with 2.0 on the horizon. (Actually, Fresh 2 is already available in beta, with documentation and a formal launch coming soon. If you want access to Fresh 2, let us know in Discord.) This next major version is a material overhaul of the internal APIs, but should unlock the ability to create composable and modular middleware. Stay tuned!
Beyond Deno 2
Last year we released Deno 2, expanding what developers already love about Deno — it’s simplicity, all-in-one toolchain, built-in web standards APIs and TypeScript support — to become more flexible and usable in a wider variety of projects and use cases:
- backwards compatibility with Node and npm
- monorepo and workspace support
- improved package management with JSR and npm
- enterprise features such as LTS and dedicated enterprise support channel
This year, we’ll focus on making Deno more reliable and efficient for production scenarios. For instance, in our next minor release, we plan to improve observability, tracing, and debugging. We’re also working towards much faster cloud performance in Deno and our commercial product, Deno Deploy, which hope to talk more about soon.
Stay in the loop — follow us on Bluesky, Twitter, YouTube, and Discord.