Deno 1.31 reads the dependency map projects already have
Package.json discovery and embedded Node compatibility reduce the translation needed to run existing dependencies in Deno. Script and native-module support still have explicit boundaries.
A runtime can execute TypeScript while still asking a project to describe its dependencies differently from the rest of its tools. That creates migration work before any application logic changes. Deno 1.31 reduces that work by discovering package.json and using its dependencies to resolve bare imports.
The February 24 announcement describes package.json support together with stable Node-API support and an embedded Node compatibility layer. Its 1.31.0 release notes record the underlying changes, including discovery, dependency resolution and language-server support. The release tag is dated February 23, while this post follows the public announcement on February 24.
I find TypeScript's ecosystem more compelling than the language itself. A runtime that can use the dependency declarations already present in a web project offers a practical way to investigate another execution environment without first translating the entire package graph.
Bare imports need a source of package meaning
An import such as import chalk from "chalk" does not contain the location of the module. Something has to connect the name with a dependency. With package.json discovery, Deno can use the declared package relationship to install and resolve that import.
This makes existing source code more portable between tool arrangements. The application can keep its bare specifier while the runtime reads the project metadata explaining which package it refers to. Compatibility here concerns both the import expression and the dependency description supporting it.
The release notes show that the implementation extends beyond deno run. Bare-specifier support reaches more subcommands and the language server. That matters because runtime execution and editor understanding need to agree about the dependency a source file names. An import that works only when executed would leave other parts of the development workflow inconsistent.
Import maps remain supported, and the announcement still describes them as the preferred way to map bare specifiers in Deno. Package.json support does not require claiming that the existing Deno arrangement has disappeared. It gives projects another source of dependency information, especially where that information already exists for other tools.
The maintenance entries also include resolving node_modules relative to package.json instead of the current directory. This preserves the relationship to the project definition when a command runs from a different working directory. Dependency resolution should not accidentally switch its base merely because a user invoked a tool from a nearby folder.
Node compatibility becomes part of the installed runtime
Earlier Deno releases obtained Node compatibility code through standard-library modules. The announcement explains that this required fetching the relevant standard-library version when the runtime changed. Repeated execution also carried startup work associated with that layer.
Deno 1.31 embeds the compatibility implementation in the runtime and uses V8 snapshots. Compatibility code becomes part of what the installed runtime carries, reducing the separate loading work. This also ties the implementation of Node-compatible built-ins to the runtime release containing it.
Built-in imports can use node: specifiers, such as node:fs. These are distinct from an arbitrary package called fs in a dependency map. The specifier identifies the runtime-provided compatibility module. Application code can therefore name its reliance on a Node built-in explicitly.
Embedding the layer does not establish that every Node program works unchanged. The release notes still contain individual compatibility fixes and additions. It changes where the implementation lives and how it starts, while the supported behavior continues to be implemented module by module.
This is a useful distinction for TypeScript users. Types and module resolution can describe a dependency correctly while execution still depends on host APIs. Reading the existing package map solves a discovery problem. Providing compatible built-ins solves a different runtime problem.
Stable Node-API support helps native dependencies
Node-API no longer requires the unstable flag in Deno 1.31. This allows npm packages relying on that API to use the supported path without opting into unstable runtime facilities. The announcement also records compatibility fixes and acknowledges remaining bugs.
The change matters because a package graph can include native components even when application code is entirely TypeScript. Being able to find a package is insufficient if one of its runtime dependencies requires a native interface that the host does not support.
The release notes include repairs to property descriptors and name handling in the Node-API implementation. Those details illustrate the granularity of compatibility. A package can exercise a particular descriptor variant that another package never uses, so useful ecosystem coverage requires correct behavior below the headline API availability.
I am interested in this sort of migration path because it leaves room to evaluate the runtime around an actual dependency set. It makes the existing libraries part of the comparison. A TypeScript entry point alone would say little about whether the package graph can run.
Task scripts are supported within limits
Deno task can now run scripts from package.json. The announcement explicitly limits this initial support to simple scripts and names rimraf and cross-env as examples that do not yet work. That qualification belongs beside the feature because existing project scripts may depend on precisely those command-line helpers.
A script name is another entry point into project conventions. Supporting it avoids requiring developers to memorize a second command for the same intended operation. The command inside that script still has to be executable under the runtime's task implementation and compatibility rules.
The announcement demonstrates a Vite project as a more substantial example, while retaining the script limitations. That is evidence of a supported workflow, not a universal claim about every browser build configuration. Projects can benefit from package discovery while still needing to examine individual scripts.
The release also deprecates deno bundle. Its explanation says browser bundling has different requirements from making a self-contained server-side file, and growing Node and npm compatibility makes the runtime command harder to support. Deno is expanding access to existing project dependencies while leaving browser bundling to tools designed for that task. This makes the boundary between running a project and producing its browser artifacts more explicit.