Deno 1.42: Better dependency management with JSR
Our vision with Deno is to simplify programming, and one important aspect of that is managing dependencies. While npm has grown to be the most successful open source registry, consuming and publishing modules there has grown increasingly complex.
Built on npm’s success, JSR offers a modern, TypeScript-first, and cross-platform-compatible registry, fully integrated into Deno.
Deno v1.42 provides more robust dependency management with
deno publish
and deno add
subcommands,
which can publish and install modules from JSR and npm. On top of that, this
release offers improved Node/npm compatibility,
several LSP improvements,
faster startup time (along with other performance benefits), and
more.
If you already have Deno installed, upgrade to version 1.42 in your terminal with:
deno upgrade
If you don’t yet have Deno installed, you can install it with one of the following commands, or many other ways.
MacOS / Linux Install
curl -fsSL https://deno.land/install.sh | sh
Windows Install
irm https://deno.land/install.ps1 | iex
Here’s an overview of what’s new in Deno 1.42:
- JSR,
deno publish
, anddeno add
- Node.js and npm compatibility
deno task
deno lint --fix
- Simpler
deno run --check
- Upcoming
deno install
changes - Language server improvements
- Performance
- V8 12.3 and TypeScript 5.4.3
DENO_FUTURE=1
environment variable
deno publish
, and deno add
JSR, JSR is a new open source registry for modern JavaScript and TypeScript packages. Read about why we built JSR.. JSR is an absolute pleasure to use. It takes all the headaches away from distributing TypeScript and JavaScript. We’re sure you’ll love it.
In 1.42, first class support for JSR is added to Deno. That means without any additional tooling, you can consume and publish modules to JSR.
There are two new subcommands. First is deno add
. This works just like
npm add
but defaults to JSR packages. For example, if you want to use
@std/assert
from JSR, you would just run
deno add @std/assert
This will add an import map entry allowing you to easily import in your code
import { assertEquals } from "@std/assert";
assertEquals(1, 2);
Note that deno add
also supports adding npm packages with the npm:
prefix.
For module authors deno publish
does what you expect, it publishes to JSR.
Read all about it here.
JSR is also fully baked into Deno’s LSP and VS Code extension. Expect go-to-definition to work properly, even with TypeScript. Intellisense should work perfectly fine for JSR packages.
We’d love to hear your feedback on these new features.
Node.js and npm compatibility
Lots of improvements in this release to make Deno more compatible with Node.js:
async_hooks
module now supportsEventEmitterAsyncResource
AsyncLocalStorage.enterWith()
APIs #22994 #22740child_process.spawn()
correctly handlesnull
instdio
configuration #23048crypto
module is steadily getting more complete. In this release we addedgetRandomValues()
,subtle
,getCipherInfo()
,publicKey()
,createPublicKey()
APIs, as well as added support for more curves in multiple APIs. The changes should unblock usages of popular packages likessh2
,web-push
,octokit
and more. #22882 #22891 #23028fs
received support for Windows “junctions”,FsWatcher.ref()
,FsWatcher.unref()
andfs.statfs()
APIs #22987 #22294http
module now exportsvalidateHeaderName()
andvalidateHeaderValue()
APIs andServerResponse
now correctly supports setting HTTP methods #22630 #22616http2
received a basic support forcreateServer()
API #22708module.isBuiltin()
is now supported #22817process.arch
now supports"riscv64"
process.argv0
is now correctly setprocess.version
has been updated to returnv20.11.1
which is the latest LTS release of Node.jsprocess.setSourceMapsEnabled
is now available, but is a no-oppunycode
module works correctly #22847string_decoder.StringDecoder()
matches Node.js behavior #22933timers.setImmediate
matches Node.js API and behavior #22808util.styleText
is now supported #22758worker_threads
module received a major overhaul. It now correctly supports ES modules and CommonJS. Following APIs are now supported:parentPort
,workerData
,isMainThread
,threadId
,receiveMessageOnPort()
,ref()
,unref()
. Workers are now setup synchronously and automatically terminated when they are idle. #22841 #20794 #22950 #22647 #22884 #22815 #22766 #22778v8.serialize()
andv8.deserialize()
have been implemented #22975 #22975
As well as several improvements related to npm compatibility:
User code can now correctly import CommonJS files from the
node_modules/
directoryInternal conditional exports (exports starting with
#
, eg.#crypto
) are now supportedCSS files are correctly resolved from npm packages during type checking
Additionally, improvements were made to the performance of setting up the
node_modules/
directory - you can see up to 1.7x speed up in Deno v1.42.
deno task
Cross-platform shebang support has landed in deno task
for any shebang that
starts with #!/usr/bin/env -S
.
Given a script.ts
file and deno.json
:
#!/usr/bin/env -S deno run
console.log("Hello there!");
{
"tasks": {
"hi": "./script.ts"
}
}
Running this task now works, even on a Windows machine:
> pwd
C:\Users\david\dev\my_project
> deno task hi
Hello there!
Exit status variable
The shell now supports using $?
to get the exit code of the last run command:
{
"tasks": {
// outputs 10
"output": "deno eval 'Deno.exit(10)' || echo $?"
}
}
Improved redirect support
Input redirects and more file descriptor redirects are now implemented:
{
"tasks": {
// redirect file.txt to the stdin of gzip
"input-redirect": "gzip < file.txt",
// redirect stdout to stderr
"stdout-err": "deno run main.ts >&2",
// redirect stderr to stdout
"stderr-out": "deno run main.ts 2>&1"
}
}
Task descriptions
If you are using a JSONC file, you can now add descriptions to your tasks using comments:
{
"tasks": {
// Start development server
"dev": "deno run --watch main.ts",
/**
* Run tests with coverage and output HTML report
*/
"coverage": "deno test --coverage **/*_test.ts && deno coverage --html"
}
}
$ deno task
- dev
// Start development server
deno run --watch main.ts
- coverage
// Run tests with coverage and output HTML report
deno test --coverage **/*_test.ts && deno coverage --html
deno lint --fix
The infrastructure has been implemented to fix lint rules automatically on the command line and via quick fixes in the editor.
For example, given the following code:
window.onload = () => console.log("Hi there!");
deno lint
now outputs the following:
> deno lint
error[no-window]: window is deprecated and scheduled for removal in Deno 2.0
--> main.ts:1:1
|
1 | window.onload = () => console.log("Hi there!");
| ^^^^^^
= hint: Instead, use `globalThis`
docs: https://lint.deno.land/rules/no-window
Found 1 problem (1 fixable via --fix)
Checked 1 file
Notice the text (1 fixable via --fix)
. Let’s try that:
> deno lint --fix
Checked 1 file
> cat main.ts
globalThis.onload = () => console.log("Hi there!");
> deno lint
Checked 1 file
At the moment, this only works for three lint rules, but the list will grow over time.
--watch-exclude=...
Sometimes when using the --watch
flag, you’d rather not have certain files
trigger a restart. This is now possible with the --watch-exclude
flag:
# exclude file1.ts and file2.ts from being watched
deno run --watch --watch-exclude=file1.ts,file2.ts main.ts
You can also exclude patterns, but remember to surround it in quotes to prevent your shell from expanding them before sending the arguments to Deno:
# exclude any .js file from being watched
deno run --watch --watch-exclude='*.js' main.ts
jsr
tag and verbatim-module-syntax
lint rule
deno.json files containing name
, version
, and exports
fields are now
automatically opted into the jsr
lint rule tag.
This tag contains the following rules:
no-slow-types
verbatim-module-syntax
(fixable via--fix
)
The no-slow-types
lint rule is JSR specific and you can read about it
on jsr.io. The verbatim-module-syntax
lint rule enforces import
and export
declarations define their identifiers
as being type only when they’re used in only type positions. This is important
to ensure code published on jsr.io works in more scenarios. You can read about
verbatim module syntax in the
TypeScript 5.0 release notes.
Type checking partway through application execution no longer occurs
Previously, if you ran deno run
with the --check
flag, Deno could
potentially type check partway through execution when encountering a statically
unanalyzable dynamic import or starting a worker.
This feature had a large maintenance burden, raised some challenges with JSR,
and produced the undesirable behavior of potentially failing a running
application partway through execution. For this reason, type checking no longer
occurs after the initial type check (to emphasize: deno run --check main.ts
still type checks BEFORE executing any modules).
It’s recommended to instead use the deno check
sub command to type check these
modules if desired.
deno install
changes
Upcoming deno install
allows you to easily install and distribute executable code.
$ deno install --allow-net --allow-read https://deno.land/std/http/file_server.ts
✅ Successfully installed file_server.
$ file_server
Listening on http://127.0.0.1:4507
We have received feedback that while this command is useful, a lot of users
expected it to “install” dependencies locally to the project — just like
previously introduced deno add
does.
To better align with the expectations, deno install
will be changed in Deno 2
to installing scripts locally to the project. That is, deno install
will be an
alias to deno add
.
The current behavior will still be supported with the -g
/ --global
flag to
tell Deno that you want to install the script globally.
$ deno install --global --allow-net --allow-read https://deno.land/std/http/file_server.ts
✅ Successfully installed file_server.
Deno will now warn you and suggest to use -g
/ --global
flag if you omit it.
Language server improvements
Since v1.37, our LSP has supported completions for npm:
specifiers. In v1.42, we’ve not only added support for jsr:
specifiers, but
also completions for both package names and versions.
import "jsr:@std/a";
// "jsr:@std/archive";
// "jsr:@std/assert"; ✔️
// "jsr:@std/async";
// "jsr:@std/data-structures";
// "jsr:@std/datetime";
// ...
import "jsr:@std/assert@";
// "jsr:@std/[email protected]"; ✔️
// "jsr:@std/[email protected]";
// "jsr:@std/[email protected]";
// "jsr:@std/[email protected]";
// "jsr:@std/[email protected]";
// ...
Other improvements and fixes
- Include registry url in JSR import hover text.
- Don’t warn about local file “redirects” from .js to .d.ts files.
- Don’t apply symbol renames to vendored remote modules.
- Apply trailing slash expansion for package specifier import map keys.
Performance
This release saw a bunch of performance improvements across the board, with most notable being:
Faster startup time: 10% improvement in startup time on Linux. Bootstrap initialization is now warmed up during snapshot time and reduced memory allocations.
More efficient setTimeout
and setInterval
: Timers have undergone a
significant rewrite. Creating a million timers takes about 1.4s compared to 5.9s
in Deno 1.41, also cutting memory usage by up to 70%. We still
have a few optimizations to make, that we will be working on in the coming
months.
V8 12.3 and TypeScript 5.4.3
Deno 1.42 ships with V8 12.3 and
TypeScript 5.4.3.
The notable changes include
support for Set
methods and
support for Iterator Helpers.
Following are now available:
- Iterator.prototype.map(mapperFn)
- Iterator.prototype.filter(filtererFn)
- Iterator.prototype.take(limit)
- Iterator.prototype.drop(limit)
- Iterator.prototype.flatMap(mapperFn)
- Iterator.prototype.reduce(reducer [,initialValue])
- Iterator.prototype.toArray()
- Iterator.prototype.forEach(fn)
- Iterator.prototype.some(fn)
- Iterator.prototype.every(fn)
- Iterator.prototype.find(fn)
- Iterator.from(object)
- Set.prototype.intersection(other)
- Set.prototype.union(other)
- Set.prototype.difference(other)
- Set.prototype.symmetricDifference(other)
- Set.prototype.isSubsetOf(other)
- Set.prototype.isSupersetOf(other)
- Set.prototype.isDisjointFrom(other)
DENO_FUTURE=1
environment variable
Deno v1.42 adds a new environment variable, DENO_FUTURE=1
, which enables
changes that will take place in, the long anticipated, many times delayed,
Deno 2.
Currently DENO_FUTURE=1
enables the following changes:
- remove
window
global - remove following
Deno
APIs:Deno.Buffer
,Deno.close
,Deno.copy
,Deno.File
,Deno.FsFile.prototype.rid
,Deno.fstat
,Deno.fstatSync
,Deno.ftruncate
,Deno.ftruncateSync
,Deno.flock
,Deno.flockSync
,Deno.funlock
,Deno.funlockSync
,Deno.iter
,Deno.iterSync
,Deno.metrics
,Deno.readAll
,Deno.readAllSync
,Deno.read
,Deno.readSync
,Deno.resources
,Deno.seek
,Deno.seekSync
,Deno.shutdown
,Deno.writeAll
,Deno.writeAllSync
,Deno.write
,Deno.writeSync
In following releases we will add more changes that will happen in Deno 2,
including changes to handling of node_modules/
directory. Specficially
enabling BYONM
under DENO_FUTURE
.
If you want to future-proof your code for the upcoming major Deno 2 release, you
can set the DENO_FUTURE=1
environment variable in your shell or CI
environment.
Thank you to our contributors!
We couldn’t build Deno without the help of our community! Whether by answering questions in our community Discord server or reporting bugs, we are incredibly grateful for your support. In particular, we’d like to thank the following people for their contributions to Deno 1.42: Dimitris Apostolou, Don Jayamanne, Eric Long, Kenta Moriuchi, Nano Miratus, Sol Boucher, Viktor Marinho, cui fliter, guangwu, mash-graz, mimikun, tuhana, ud2, and Łukasz Czerniawski.
Would you like to join the ranks of Deno contributors? Check out our contribution docs here, and we’ll see you on the list next time.
Believe it or not, the changes listed above still don’t tell you everything that got better in 1.42. You can view the full list of pull requests merged in Deno 1.42 on GitHub here.
Thank you for catching up with our 1.42 release, and we hope you love building with Deno!
🍋 Fresh 2.0 is right around the corner.
Our next major Fresh release will be simpler with a more composable, Express-like API. Read more here.