Deno 2.6: dx, deno audit and finer-grained permissions for the supply chain
Deno 2.6 shipped on December 10, and reading the release notes, the theme tying almost everything together is supply chain security. This is not a release of big breaking changes: it patches practical, everyday gaps for people who use npm packages inside Deno. Here is what caught my attention.
dx: Deno’s npx, but it asks first
The new dx command runs binaries from npm and JSR packages, filling the role npx plays in Node. The announcement’s example is dx cowsay "Hello, Deno!", and you install the alias with deno x --install-alias.
The differences from deno run matter. According to the Deno blog, dx:
- defaults to
--allow-allunless you pass another permission flag; - prompts before downloading a package;
- runs lifecycle scripts automatically if you accept the prompt;
- defaults to the
npm:prefix; - errors if you pass it a local file.
The --allow-all default is the pragmatic choice for command-line tools, but it is worth knowing about. The prompt before downloading is the part I find most useful: it is exactly the moment when a typo in a package name becomes a problem.
More granular permissions
Two new flags change how denied resources behave. With --ignore-read, reading an ignored path returns NotFound instead of NotCapable. With --ignore-env, the ignored variable simply becomes undefined, with no exception:
deno run --ignore-read=/etc --ignore-env=AWS_SECRET_KEY main.ts
This is great for running third-party code that reads things “just in case” and would otherwise crash on a permission error. Along the same lines, Deno.env.toObject() now respects partial permissions: with --allow-env=SOME_SECRET, it returns only that variable.
There is also an experimental permission broker. When you set DENO_PERMISSION_BROKER_PATH to a socket path, every --allow-*, --deny-* and --ignore-* flag is ignored and each permission request goes to the broker. It is a niche feature, but it opens the door for platforms that need to decide permissions centrally.
Dependency tooling: audit, scripts and minimum age
This is the most relevant block for anyone maintaining production projects:
deno auditchecks JSR and npm dependencies against the GitHub CVE database. The experimental--socketflag adds socket.dev checks (and usesSOCKET_API_KEY, if set, for detailed reports). The stated goal is to fail CI pipelines when vulnerabilities show up.deno approve-scriptsreplacesdeno install --allow-scriptswith an interactive picker to approve or denypostinstall-style scripts per package. Approvals are saved toallowScriptsindeno.json.minimumDependencyAgeonly allows installing or updating packages that have reached a minimum age. It accepts minutes, an ISO-8601 duration (such as"P2D") or an RFC3339 timestamp, viadeno.jsonor--minimum-dependency-age.deno install --lockfile-onlyupdatesdeno.lockwithout downloading packages, handy for validating dependency changes in CI.
Minimum age is the one I most want to see adopted. Many recent attacks on popular packages depend on someone installing a compromised version in the first few hours. Waiting a few days before accepting a new version is a cheap defense.
Type checking with tsgo and other additions
With deno check --unstable-tsgo (or DENO_UNSTABLE_TSGO=1), Deno uses tsgo, TypeScript’s native compiler. The team reports roughly a 2x speedup on internal projects. tsconfig.json support also improved for compilerOptions.paths, skipLibCheck and isolatedDeclarations.
Other items:
- Source phase imports: import the compiled module instead of an instance. For Wasm, that gives you a
WebAssembly.Moduleready to instantiate. --requirepreloads CommonJS files before the main module, complementing the--preloadflag from 2.4.@types/nodenow ships by default, while still respecting a version you installed yourself.BroadcastChannelis no longer experimental.- V8 was upgraded to version 14.2.
import source addModule from "./add.wasm";
My take
Deno has always sold security through its permission model, but in practice people using npm end up with --allow-all everywhere. Version 2.6 tackles this from the right angle: instead of only tightening permissions, it gives you tools to control what enters the project (audit, script approval, minimum age) and makes denied permissions less brittle with --ignore-*.
The caveat is that several of these features are new or experimental (--socket, the broker, tsgo), so I would test them in CI before relying on them. Even so, minimumDependencyAge and deno audit are things I would turn on today in any Deno project.