deno lint and deno fmt are configured in deno.json
Both deno lint and deno fmt are configured using the same deno.json file as the rest of the project. The linter configuration is in a 'linting' or similar field, and the formatter configuration is in a 'fmt' field.
node_modules directory layout options in Deno
By default Deno uses an isolated node_modules layout similar to pnpm's: real files live in node_modules/.deno/ and packages are exposed through symlinks. Tools that expect npm's flat, hoisted layout can opt into it with nodeModulesDir: "manual" and nodeModulesLinker: "hoisted" in deno.json.
pnpm-workspace.yaml migration to deno.json
Deno does not read pnpm-workspace.yaml during resolution, but automatically migrates it when a workspace member or catalog version fails to resolve. The migration converts pnpm's packages, catalog, and catalogs fields into equivalent Deno config fields in deno.json. Workspace globs move from pnpm's packages list into a workspace array in deno.json.
Deno workspace glob depth requires explicit paths
In Deno workspace patterns, packages/* matches one level (packages/foo), and packages/*/* matches two levels. There is no ** recursive glob; add a /* segment per level instead to match deeper directory structures.
Deno workspace does not support glob exclusions
Deno's workspace field does not support exclusions like pnpm's !packages/excluded negation. List the members you want explicitly rather than excluding a few from a wildcard.
Deno catalog protocol syntax for centralized versions
Deno supports the same catalog: protocol as pnpm for sharing dependency versions across workspace members (added in Deno 2.8). The catalog: references inside each member's package.json resolve to either the default catalog or a named entry in catalogs. For example, "react": "catalog:" resolves to the default catalog, and "react": "catalog:react18" resolves to a named entry.
links field in deno.json for local packages
The `links` field in `deno.json` allows overriding dependencies with local versions during development without publishing them. It accepts paths to directories containing packages or workspaces. Both JSR and npm packages are supported. If referencing a single package within a workspace, the entire workspace will be included. This feature is only respected in the workspace root; using `links` elsewhere triggers warnings. Git-based dependency overrides are unavailable.
scopes field for overriding HTTPS imports
The `scopes` field in `deno.json` allows redirecting specific HTTPS imports to alternative paths. This is useful for substituting remote dependencies with local patched versions for debugging or temporary fixes. Scopes apply only to the root of the project; nested scopes within dependencies are ignored.
Dev dependencies in deno.json
When using `deno.json`, mark dev-only dependencies with a `// dev` comment after the import to aid code readers. The runtime does not require distinguishing between development and production dependencies since it only loads dependencies actually used in the executing code.
devDependencies field in package.json
When using `package.json`, dev dependencies can be added to the separate `devDependencies` field. The runtime only loads and installs dependencies that are actually used in the code being executed.
preferPackageJson setting in deno.json
Set `preferPackageJson: true` in `deno.json` to make `deno add`, `deno install`, and `deno remove` write to `package.json` by default instead of `deno.json`, without passing `--package-json` each time.
Global cache for dependencies (DENO_DIR)
By default, Deno uses a global cache directory (`DENO_DIR`) for downloaded dependencies. This cache is shared across all projects. Deno stores dependencies in a global cache and creates a local `node_modules` directory only when a project has a `package.json`. This behavior can be controlled with the `nodeModulesDir` option in `deno.json`.
deno.lock file automatic maintenance
Deno automatically maintains a `deno.lock` file that records the exact version and integrity hash of every dependency, and verifies it on subsequent runs. The lockfile should be committed to version control.
Vendoring dependencies with deno.json
To cache all dependencies locally in a `vendor` directory, add `"vendor": true` to `deno.json`. Alternatively, run `deno install --entrypoint main.ts` to cache dependencies immediately. After vendoring, use `--cached-only` flag to run without internet access.
Overriding npm packages locally
Deno supports linking npm packages with local versions through the `links` field in `deno.json`. This requires a `node_modules` directory. With `nodeModulesDir: auto`, the directory is recreated on each run (slightly increasing startup time but ensuring the latest version). With `nodeModulesDir: manual` (default with package.json), run `deno install` after updating the package. Specifying a local npm package will purge npm packages from the lockfile, which may cause npm resolution to work differently. The npm package name must exist in the registry, even if using a local copy.
Workspace publishing with deno publish
In a workspace, deno publish publishes every workspace member that has a name and version, in dependency order.
deno.json configuration for publishing to JSR
To publish a package to JSR, define a name (always scoped as @scope/name), a version, and an exports field in deno.json. Example: {"name": "@scope/my-package", "version": "1.0.0", "exports": "./mod.ts"}. The scope must be created on jsr.io the first time you publish.
Minimum supply chain baseline configuration
The recommended minimum supply chain baseline configuration in deno.json is: "imports": { /* centralize versions */ }, "vendor": true, "lock": { "frozen": true }. Commit deno.json, deno.lock, and (if using vendor) the entire vendor/ directory.
Minimum dependency age configuration
Minimum dependency age can be configured in three places: deno.json using "minimumDependencyAge" field (accepts ISO-8601 duration like P3D or PT72H, an integer as minutes, an absolute cutoff date, or RFC3339 timestamp, or 0 to disable), CLI flag --minimum-dependency-age with the same formats, or .npmrc using min-release-age field with whole number of days only (Deno 2.8+).
deno.json test file configuration example
File inclusion and exclusion for tests is configured in deno.json under the test object with include and exclude fields. Example: {"test": {"include": ["src/**/*.test.ts"], "exclude": ["src/fixtures/"]}}