Deno 2.4: deno bundle is back
To upgrade to Deno 2.4, run the following in your terminal:
deno upgrade
If Deno is not yet installed, run one of the following commands to install or learn how to install it here.
# Using Shell (macOS and Linux):
curl -fsSL https://deno.land/install.sh | sh
# Using PowerShell (Windows):
iwr https://deno.land/install.ps1 -useb | iex
What’s new in Deno 2.4
deno bundle
- Importing text and bytes
- Built-in OpenTelemetry is now stable
- Modify the Deno environment with the new
--preload
flag - Easier dependency management with
deno update
- Collect script coverage with
deno run --coverage
DENO_COMPAT=1
- Permission changes
- Conditional
package.json
exports deno run
bare specifiersdeno fmt
XML and SVG files- Better
tsconfig.json
support - Simpler Node globals
- Local npm packages
- Node.js API support
- LSP improvements
- Other fun things
- Acknowledgements
deno bundle
Deno 2.4 restores the
deno bundle
subcommand for
creating single-file JavaScript or TypeScript bundles. It supports both
server-side and browser platforms, works with npm and JSR dependencies, and
includes automatic tree shaking and minification via esbuild.
# Bundle with minification
$ deno bundle --minify main.ts
# Set platform to browser (defaults to "deno")
$ deno bundle --platform browser --output bundle.js app.jsx
# Also generate an external sourcemap
$ deno bundle --platform browser --output bundle.js --sourcemap=external app.jsx
For long time Deno users, you may remember we used to have deno bundle
, which
was subsequently deprecated.
JavaScript bundling is an incredibly complex problem, and we did not believe we
could build deno bundle
properly. Now that deno bundle
uses
esbuild
under the hood, it is here to stay.
We’re working on a runtime API to make bundling available programmatically in the future. On top of that, we plan to add plugins, allowing you to customize how the bundler processes modules during the build process.
For more information visit
deno bundle
reference
and the bundling docs page
Importing text and bytes
Have you ever wanted to include a data-file of some sort in your JavaScript module graph? Maybe a markdown file, icons, or a binary blob? Until now you would have had to load these files at runtime, carefully ensuring the assets were shipped alongside your code:
const image = Deno.readFileSync(import.meta.resolve("./image.png"));
const text = await Deno.readTextFile(import.meta.resolve("./log.txt"));
In Deno 2.4, you can link these files into the JavaScript graph with the flag
--unstable-raw-imports
:
import message from "./hello.txt" with { type: "text" };
import bytes from "./hello.txt" with { type: "bytes" };
import imageBytes from "./image.png" with { type: "bytes" };
console.log("Message:", message);
// Message: Hello, Deno!
console.log("Bytes:", bytes);
// Bytes: Uint8Array(12) [
// 72, 101, 108, 108, 111,
// 44, 32, 68, 101, 110,
// 111, 33
// ]
Deno.serve((_req) => {
return new Response(imageBytes, {
status: 200,
headers: {
"Content-Type": "image/png",
"Content-Length": imageBytes.byteLength.toString(),
},
});
});
// Shows image.png at localhost:8000
You can use this with deno bundle
, simplifying the process of importing
non-JavaScript files in your application and avoiding manual file I/O or
middleware.
import icon from "./icon.png" with { type: "bytes" };
console.log("Icon", icon);
$ deno bundle --unstable-raw-imports -o app.js main.ts
⚠️ deno bundle is experimental and subject to changes
Bundled 2 modules in 7ms
app.js 268B
$ deno app.js
Icon Uint8Array(69) [
137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13,
73, 72, 68, 82, 0, 0, 0, 1, 0, 0, 0, 1,
8, 2, 0, 0, 0, 144, 119, 83, 222, 0, 0, 0,
12, 73, 68, 65, 84, 120, 218, 99, 96, 96, 96, 0,
0, 0, 4, 0, 1, 200, 234, 235, 249, 0, 0, 0,
0, 73, 69, 78, 68, 174, 66, 96, 130
]
Additionally, this feature works with deno compile
, so that you can embed
assets into your final compiled binary.
import dictData from "./dictionary.txt" with { type: "text" };
const DICT = dictData.split(" ");
while (true) {
let input = prompt("> Enter the word to check: ");
input = input.trim();
if (!input) {
continue;
}
if (!DICT.includes(input)) {
console.error(`${input} is not a known word`);
} else {
console.log(`${input} is a known word`);
}
}
$ deno compile --unstable-raw-imports spellcheck.js
Compile file:///dev/spellcheck.js to spellcheck
$ ./spellcheck
> Enter the word to check: deno
deno is a known word
> Enter the word to check: asdf
asdf is not a known word
Bytes and text imports add to Deno’s existing ability to import JSON and Wasm files natively:
import file from "./version.json" with { type: "json" };
console.log(file.version);
// "1.0.0"
import { add } from "./add.wasm";
console.log(add(1, 2));
// 3
While the ability to import various file types have been around (such as in Next.js and other frameworks), these approaches are not spec-friendly and introduce unnecessary complexity via domain-specific languages and ahead-of-time compilers that modify the language.
We’ve wanted to add importing other file types earlier, but also want to be aligned with the spec and avoid introducing breaking changes. Astute observers might note that this feature actually goes ahead of current spec (here’s the proposal for import attributes). However, due to ongoing discussions and proposed upcoming features about this feature, we are confident this implementation is in the right direction.
Built-in OpenTelemetry is now stable
In 2.2, we introduced
built-in OpenTelemetry support,
which auto-instruments the collection of logs, metrics, and traces for your
project. We’re excited to announce that it is now stable in 2.4, which means you
no longer need --unstable-otel
flag:
$ OTEL_DENO=1 deno --allow-net server.ts
Listening on http://localhost:8000/
Deno’s OpenTelemetry support simplifies observability in your JavaScript projects, as it automatically associates logs with HTTP requests, works in Node with no additional config, and is available to all your projects in our new Deno Deploy:
console.log
s and associates them with HTTP requests. Here we click view a trace from a log, then view all logs within that HTTP request.
Note that you will still need to set the environment variable OTEL_DENO=1
to
enable instrumentation, since it uses additional resources and don’t want it on
all the time.
For more information about Deno’s OpenTelemetry support, check out the following resources:
- Zero-config Debugging with Deno and OpenTelemetry
- How to get deep traces in your Node.js backend with OTel and Deno
- Easier debugging with auto-instrumented OTel in Deno Deploy
- Deno OpenTelemetry reference documentation
--preload
flag
Modify the Deno environment with the new We’ve landed a new --preload
flag that will execute code before your main
script. This is useful if you are building your own platform and need to modify
globals, load data, connect to databases, install dependencies, or provide other
APIs:
delete Deno;
globalThis.window = globalThis;
console.log(Deno);
$ deno --preload setup.ts main.ts
error: Uncaught (in promise) ReferenceError: Deno is not defined
console.log(Deno);
^
at file:///main.ts:1:13
While we’ve traditionally been cautious about allowing user code to modify the
runtime, it’s become clear that there are enough circumstances in which this is
needed. This flag is available to use in
deno run
,
deno test
and
deno bench
subcommands.
deno update
Easier dependency management with We’ve added a new subcommand,
deno update
, which
allows you to update your dependencies to the latest versions:
deno update --latest
.
This command will update npm and JSR dependencies listed in deno.json
or
package.json
files to latest semver compatible versions.
# Ignore semver constraints
deno update --latest
# Filter packages that match "@std/*"
deno update "@std/*"
# Include all workspace members
deno update --recursive
deno outdated --update
did the same thing, but to save you the headache of
typing additional characters, we added the alias deno update
.
For more information about deno update
, check out
the Deno docs.
deno run --coverage
Collect script coverage with deno test --coverage
will execute your test suite while collecting coverage information, which is a
breeze to use. However, in some situations like if you need to spawn a
subprocess as part of the test suite,
deno test
would not
collect the coverage of the subprocess, making the report spotty.
Deno 2.4 alleviates this problem by introducing the --coverage
flag that you
can pass to deno run
.
You can also use DENO_COVERAGE_DIR
environment variable instead.
function foo(a: number, b: number) {
if (a > 0) {
console.log(a);
} else {
console.log(a);
}
if (b > 0) {
console.log(b);
} else {
console.log(b);
}
}
const [a = 0, b = 0] = Deno.args;
foo(+a, +b);
$ deno run --coverage main.ts
0
0
$ deno coverage
| File | Branch % | Line % |
| --------- | -------- | ------ |
| main.ts | 0.0 | 57.1 |
| All files | 0.0 | 57.1 |
To learn more about coverage collection and presentation visit Deno docs.
Oh by the way, HTML coverage report now supports dark mode 🤫.
DENO_COMPAT=1
We’ve introduced a new environment variable, DENO_COMPAT=1
, that will tell
Deno to enable the below flags to improve ergonomics when using Deno in
package.json
-first projects:
--unstable-detect-cjs
--unstable-node-globals
--unstable-bare-node-builtins
--unstable-sloppy-imports
For instance:
# Before 2.4
deno --unstable-detect-cjs --unstable-node-globals --unstable-bare-node-builtins --unstable-sloppy-imports app.js
# 2.4
DENO_COMPAT=1 deno app.js
In the future, the scope of this environmental variable might be expanded
further — eg. to not require npm:
prefixes when
deno install
ing
packages.
We are also stabilizing the --unstable-sloppy-imports
flag to become
--sloppy-imports
, which tells Deno to infer file extensions from imports that
do not include them. While Deno generally encourages requiring file extensions
to avoid inefficiencies such
as probing the filesystem, the
--sloppy-imports
flag is a way to run code that uses extensionless imports.
Permission changes
The
--allow-net
flag
now supports subcomain wildcards and CIDR ranges:
const res1 = await fetch("http://test.foo.localhost");
const res2 = await fetch("http://test.bar.localhost");
$ deno --allow-net=*.foo.localhost subdomain_wildcards.ts
Response {
url: "http://test.localhost",
...
}
┏ ⚠️ Deno requests net access to "test.bar.localhost:80".
┠─ Requested by `fetch()` API.
┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.
┠─ Learn more at: https://docs.deno.com/go/--allow-net
┠─ Run again with --allow-net to bypass this prompt.
┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions) >
const res1 = await fetch("http://192.168.0.128:8080");
const res2 = await fetch("http://192.168.0.1:8080");
$ deno --allow-net=192.168.0.128/25 main.ts
Response {
url: ""http://192.168.0.128:8080"",
...
}
┏ ⚠️ Deno requests net access to "192.168.0.1:8080".
┠─ Requested by `fetch()` API.
┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.
┠─ Learn more at: https://docs.deno.com/go/--allow-net
┠─ Run again with --allow-net to bypass this prompt.
┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions) >
Deno 2 added
--allow-import
flag
that allows you to specify which remote hosts Deno can download and execute code
from.
This release adds a complimentary --deny-import
flag that allows to explicitly
block certain hosts.
By default Deno allows to import code from several hosts:
deno.land:443
jsr.io:443
esm.sh:443
cdn.jsdelivr.net:443
raw.githubusercontent.com:443
user.githubusercontent.com:443
import * as cowsay from "https://cdn.jsdelivr.net/npm/cowsay";
$ deno main.ts
Now, you can disallow importing code from one of the default hosts:
$ deno --deny-import=cdn.jsdelivr.net main.ts
error: Requires import access to "cdn.jsdelivr.net:443", run again with the --allow-import flag
at file:///main.ts:1:25
To further supplement --allow-import
usages, the
Deno.permissions
runtime
API has been fixed to support "import"
type:
console.log(Deno.permissions.query({ name: "import" }));
// Promise { PermissionStatus { state: "prompt", onchange: null } }
Finally, the Deno.execPath()
API doesn’t require read permissions anymore:
console.log(Deno.execPath());
# Deno 2.3
$ deno main.ts
┏ ⚠️ Deno requests read access to <exec_path>.
┠─ Requested by `Deno.execPath()` API.
┠─ To see a stack trace for this prompt, set the DENO_TRACE_PERMISSIONS environmental variable.
┠─ Learn more at: https://docs.deno.com/go/--allow-read
┠─ Run again with --allow-read to bypass this prompt.
┗ Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) >
# ✅ Now
$ deno main.ts
/dev/.deno/bin/deno
We made this update because in common scenarios, requiring read permission ends up less secure than not requiring permissions. For example, if a user wants to spawn a Deno subprocess using the current executable, they would do something like:
new Deno.Command(Deno.execPath(), { args: ["eval", "1+1"] }).outputSync();
And to run it:
# Deno 2.3
$ deno --allow-read --allow-run=deno spawn.ts
# ✅ Now
$ deno --allow-run=deno
Before Deno 2.4, it was possible to limit the scope of --allow-read
flag, but
it required upfront knowledge of where the Deno executable was or a bit of shell
expansion trickery. Most users understandably opted to give a blanket
--allow-read
flag instead.
Not requiring read permissions allows the above program to be run with just
--allow-run=deno
flag.
package.json
exports
Conditional This version ships with support for conditional exports in npm packages.
Conditional exports is a mechanism that allows npm packages to use different exports depending on the user provided conditions.
The stark example here is
the react-server
condition
that libraries from the React ecosystem can use to swap out exports for use with
Server Components.
import react from "npm:react@19.1.0";
console.log(react.Component);
$ deno app.jsx
Component: [Function: Component]
$ deno --conditions=react-server app.jsx
undefined
You can specify arbitrary conditions and as many of them as you want. If the
flag is not used Deno uses following conditions by default: deno
, node
,
import
, default
.
We expect most users to not have to use this flag directly, but is a crucial option for the tooling you might depend on.
deno run
bare specifiers
Deno v2.4 now supports using bare specifiers as entry points in
deno run
.
Imagine you had a deno.json
like this:
{
"imports": {
"lume/": "https://deno.land/x/lume@v3.0.4/",
"file-server": "jsr:@std/http/file-server",
"cowsay": "npm:cowsay"
}
}
You might have expected to be able to deno run file-server
and be done with
it. Unfortunately, before Deno 2.4, this didn’t work:
# Before Deno v2.4
$ deno run -ERW lume/cli.ts
error: Module not found "file:///dev/lume/cli.ts".
$ deno run file-server
error: Module not found "file:///dev/file-server".
$ deno run -ER cowsay "Hello there!"
error: Module not found "file:///dev/cowsay".
However, in 2.4:
# ✅ In Deno 2.4
$ deno run -ERW lume/cli.ts
🍾 Site built into ./_site
$ deno run file-server
Listening on ...
$ deno run -ER cowsay "Hello there!"
______________
< Hello there! >
--------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
In most cases you can also omit run
subcommand, like so
deno -ER cowsay "Hello there!"
deno fmt
XML and SVG files
deno fmt
will know
automatically format .xml
and .svg
files for you:
<svg width="100" height="100">
<circle cx="50" cy="50"
r="40" stroke="green" stroke-width="4"
fill="yellow" />
</svg>
$ deno fmt
/dev/circle.svg
Formatted 1 file
$ cat circle.svg
<svg width="100" height="100">
<circle
cx="50"
cy="50"
r="40"
stroke="green"
stroke-width="4"
fill="yellow"
/>
</svg>
Additionally, formatting .mustache
templates is now supported, but requires
--unstable-component
flag or unstable.fmt-component
option in deno.json
.
tsconfig.json
support
Better Deno automatically discovers tsconfig.json
files next to deno.json
and/or
package.json
files.
This release also brings better handling for tsconfig.json
files, with added
support for "references"
, "extends"
, "files"
, "include"
and "exclude"
options. That means you can expect a much better experience when working with
popular frontend frameworks like
Vue, Svelte,
Solid,
Qwik and more.
Simpler Node globals
Deno v2.0 added the process
global
for improved compatibility with existing npm ecosystem. But there are more
global variables that were not available in Deno for user code, but were
available for npm packages:
Buffer
global
setImmediate
clearImmediate
Additionally, globals like setTimeout
and setInterval
(as well as their
clear*
counterparts) are different globals depending if the context was user
code or in an npm dependency.
To achieve this bifurcation, we used a fairly complex setup hooking into V8 internal APIs to decide if a global is available at a particular call site or not. While the solution was clever, it comes with a high performance cost — on each access of one of these globals, we were walking the stack and checking if the call site is coming from an npm package. Finally, the mental overhead of understanding which globals are available where is non-trivial.
In this release, we’ve made Buffer
, global
, setImmediate
and
clearImmediate
available to user code as well. This helps if you are running
an existing Node.js project that relies on these globals, as you no longer need
to use the --unstable-node-globals
flag to expose them, since they are now
available everywhere all the time.
Local npm packages
In
Deno v2.3, we introduced a way to use local npm packages.
We received a lot of positive feedback about this issue, but some of you raised
concerns that the patch
option can be easily confused with npm patch
.
The option has been renamed to links
(to better reflect npm link
equivalent
functionality). You will receive a deprecation warning when using patch
option
instead of links
.
{
+ "links": [
- "patch": [
"../cowsay"
]
}
In the future we might support npm patch
equivalent functionlity out of the
box. If you depend on this tool,
let us know.
Node.js API support
We’ve improved support for Node.js APIs again. Aside from the numerous additions
and fixes that you can dive into in the list below, the highlight is support for
the glob
API, as well as
achieving over 95% compatibility for modules such as node:buffer
,
node:events
, node:querystring
, node:quic
and node:wasm
.
We plan to keep increasing these compatibility numbers in the next release with
focus on modules such as node:crypto
, node:http
, node:tls
, node:worker
and node:zlib
.
Additionally, Deno 2.4 will use @types/node
version 22.15.14 by default when
type checking.
Finally, here’s the full list of Node.js API fixes:
- Add
fs.glob
,fs.globSync
,fs.promises.glob
process.loadEnvFile
correctly returnsundefined
- Add
internal/http2/util
module - Add
fs.fchmod
andfs.fchmodSync
- Add
fs.fchown
andfs.fchownSync
- Add
fs.lchmod
,fs.promises.lchmod
andfs.lchmodSync
- Add AES CTR to supported ciphers list
- Add assert.CallTracker
- Add
events.getMaxListeners
- Add key length validation in
DiffieHellman.prototype.computeSecret
- Type check
LibuvStreamWrap.writeBuffer
- Add validation to
Cipheriv
methods - Align input validation of
Buffer.compare
node:tls
allowsrejectUnauthorized: false
- Check OOB when writing to
Buffer
- Make
Buffer.fill
correct - Correct
kMaxLength
value ofnode:buffer
net.createInterface
doesn’t require env permission- Add
crypto.timingSafeEqual
- Deprecate
Hash
andHmac
constructors dgram
multicast group membershipcrypto.DiffieHellman
constructor behaviors- Don’t use user manipulated Response objects, use correct
rawHeaders
structure - Emit
worker
event when a new worker thread is created - Enable
Buffer
pool for strings - Export
assert.CallTracker
as named export - Add
fs.promises.lchown
andfs.promises.lutimes
- Export
StatementSync
fromnode:sqlite
- Fix
Buffer.inspect
compatiblity - Fix
crypto.pbkdf2
compat - Fix
Database#exec
should return undefined - Fix
EventEmitter.on
- Fix
getEventListeners
innode:events
- Fix
addAbortListener
- Fix assertion error message of assert.ok
- Fix buffer.includes edge cases
- Fix buffer.indexOf for ucs2 encoding
- Fix dns.lookup when promisified with
options.all
- Fix error type in
crypto.DiffieHellman
constructor - Fix
events.getEventListeners
- Fix
events.once
- Correctly export
loadEnvFile
fromnode:process
- Fix
fs.watchFile
trigger - Fix function error message in
invalidArgTypeHelper
- Fix input validation of
crypto.hkdf
- Fix inspect of
CustomEvent
- Fix oneshot hash validation
- Fix prototype of
asymmetricKeyDetails
ofAsymmetricKeyObject
- Fix
ReferenceError
innode:stream
- Fix validation of input in
events.setMaxListeners
- Handle
-p
flag inspawn
- Handle
null
ssl options innode:https
- Hold weak reference to SQLite database in instances
- Implement
before
andafter
hooks innode:test
- Implement
crypto.Certificate
API - Implement
dgram.setBroadcast
- Implement
dgram.setMulticastLoopback
- Implement
dgram.setMulticastTTL
- Improve
assert.fail
- Improve
assert.ifError
- Improve comparison of faked objects in
assert.deepStrictEqual
- Improve
getaddrinfo
compatibility - Improve input validations of
stream/consumers
- Improve
crypto.scrypt
support - Include
assert.ok
innode:test
- Keep BOM in
Buffer.toString('utf8')
- Make
Buffer
work with resizable ABs - Make conditional exports work in
require()
- Make
DatabaseSync.readOnly
optional - Mark pool
ArrayBuffer
as untransferable - Match WebCrypto tag too small error msg with Node
Module.wrap
cleanup fornpm:v8-code-cache
node:buffer
validatesINSPECT_MAX_BYTES
- Pass Node.js specific flags via
NODE_OPTIONS
env var inspawn
- Prevent stdin double read
- Remove duplicated stream classes
- Return
undefined
instead ofnull
innode:sqlite
- Return values in
node:domain
- Stub
crypto.getFipsCrypto
tofalse
- Support 2nd arg of
EventEmitter.prototype.listenerCount
- Support
DEP0005
deprecation warning - Support HTTP over unix sockets
- Support
KeyObject
incrypto.publicEncrypt
/crypto.privateDecrypt
- Support mTLS connections
- Throw invalid state from
crypto.getAuthTag
- Support TLS server unref
- Update
crypto.decipherIv
error properties - Update interaction between event emitters and domains
- Update message for
MaxListenersExceededWarning
- Use “localhost” as default tls hostname
- Validate auth tag for GCM mode cipher
- Validate prime bigint candidate
- Validate
randomUUID()
options - Fix
ServerResponse.req
not being set - Throw on
assert.deepStrictEqual({}, Object.create(null))
- Support for
t.skip
andt.todo
innode:test
- Don’t return a smi from
zlib.crc32
LSP improvements
The Deno LSP received numerous improvements including:
deno.config
option in now correctly handled outside of workspace- Jupyter cells correctly handle
for await
and respect media type fortsx
- Use correct resolution kind when checking for no-export-npm
- Lookup bare workspace specifiers for auto-import
- Lookup mapped npm specifier resolutions for auto-import
- Lookup patched jsr packages for auto-import
- Use canonicalized fallback filesystem root
- Truncate JSON files larger than 10Mb
- Don’t diff 10,000+ line files for formatting
- Discard quick fixes importing /node_modules/ paths
- Do not warn about unscoped package name
- Don’t cache jsxImportSource on lockfile-only changes
- Don’t show no-export diagnostics for type-only npm imports
Other fun things
fetch
now works over Unix and Vsock sockets - create an instance ofDeno.HttpClient
with a properproxy
option:
const client = Deno.createHttpClient({
proxy: {
transport: "unix",
path: "/path/to/unix.sock",
},
// or
proxy: {
transport: "vsock",
cid: 2,
port: 80,
},
});
await fetch("http://localhost/ping", { client });
deno serve
now supportsonListen()
callbacks:
export default {
fetch(req) {
return new Response("Hello world!");
},
onListen(addr) {
console.log(
`😎 Hello world server started on ${addr.hostname}:${addr.port}`,
);
},
} satisfies Deno.ServeDefaultExport;
$ deno serve server.ts
😎 Hello world server started on 0.0.0.0:8000
- Better management of Jupyter kernels with
deno jupyter
:
# Give kernel an explicit name
$ deno jupyter --install --name="deno_kernel"
✅ Deno kernelspec installed successfully at /Jupyter/kernels/deno_kernel.
# Don't overwrite existing kernel by mistake
$ deno jupyter --install --name="deno_kernel"
error: Deno kernel already exists at /Jupyter/kernels/deno_kernel, run again with `--force` to overwrite it
# Give a display name to the kernel
deno jupyter --install --display="Deno 2.4 kernel"
# Now you will see "Deno 2.4 kernel" in the kernel selector UI
- Lint plugins can now access comments
export default {
name: "my-lint-plugin",
rules: {
"my-lint-rule": {
create(context) {
return {
Program(node) {
console.log("Top level comments", node.comments);
},
FunctionDeclaration(node) {
const all = ctx.sourceCode.getAllComments();
const before = ctx.sourceCode.getCommentsBefore(node);
const after = ctx.sourceCode.getCommentsAfter(node);
const inside = ctx.sourceCode.getCommentsInside(node);
console.log({ program, all, before, after, inside });
},
};
},
},
},
} satisfies Deno.lint.Plugin;
deno bench
anddeno coverage
tables are now Markdown compatible
You can now directly copy-paste them into Markdown documents with proper rendering
# Before
-----------------------------------
File | Branch % | Line % |
-----------------------------------
parser.ts | 87.1 | 86.4 |
tokenizer.ts | 80.0 | 92.3 |
-----------------------------------
All files | 86.1 | 87.4 |
-----------------------------------
# After
| File | Branch % | Line % |
| ------------ | -------- | ------ |
| parser.ts | 87.1 | 86.4 |
| tokenizer.ts | 80.0 | 92.3 |
| All files | 86.1 | 87.4 |
- Listening for Ctrl+Close (
SIGHUP
) now works correctly on Windows
// This will now work correctly on Windows
Deno.addSignalListener("SIGHUP", () => {
console.log("Got SIGHUP");
});
Acknowledgments
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 2.4: 林炳权, André Lima, Andy Vu, Asher Gomez, Boye Lillejord-Nygård, chirsz, Christian Svensson, Clarence Delmacio Manuel, ctrl+d, Cyan, Daniel Osvaldo R, David Emanuel Buchmann, Edilson Pateguana, Efe, Elias Rhouzlane, familyboat, Hajime-san, ikkz, James Bronder, Janosh Riebesell, JasperVanEsveld, Jeff Hykin, Jonh Alexis, Kenta Moriuchi, Kingsword, Laurence Rowe, Lino Le Van, LongYinan, Marshall Walker, MikaelUrankar, nana4gonta, narumincho, Nicholas Berlette, scarf, Scott Kyle, sgasho, Simon Lecoq, stefnotch, Timothy J. Aveni, ud2, Volker Schlecht, and zino.
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 2.4. You can view the full list of pull requests merged in Deno 2.4 on GitHub.
Thank you for catching up with our 2.4 release, and we hope you love building with Deno!
🚨️ There have been major updates to Deno Deploy! 🚨️
- Improved Playgrounds with livestreaming logs, traces, and templates like Next.js
- Automatic and immediate observability and telemetry
- Simpler management for environment variables
and much more!