new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Deno · Fundamentals · all subjects

workspaces

30 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Workspace definition in deno.json

A workspace is defined in the root deno.json file using the 'workspace' property, which contains an array of directories containing deno.json and/or package.json configuration files. Each directory in the workspace array is expected to have its own deno.json or package.json file.

Workspace member configuration types

Each workspace member directory can contain: (1) only a deno.json (Deno-first package), (2) both a deno.json and package.json (hybrid package for migration or when Node metadata is needed), or (3) only a package.json (Node-first package that participates in the Deno workspace).

Workspace member package resolution

When a workspace member contains only a package.json, it can still be imported from anywhere else in the workspace using the 'name' field from that package.json file. Deno resolves the bare specifier as long as the directory is listed in the root workspace configuration, enabling gradual adoption of Deno tooling without immediately adding deno.json to every Node package.

Workspace pattern matching with wildcards

Deno supports wildcard patterns for workspace member folders. The pattern 'some-path/*' matches files and directories directly within some-path (first level only). The pattern 'some-path/*/*' matches files and directories within subdirectories of some-path (second level). Each '/*' segment corresponds to a specific folder depth.

Workspace recursive matching with double asterisk

Use '**' to match directories at any depth below a base path. For example, 'packages/**' matches 'packages/foo', 'packages/foo/subpackage', and any deeper directories that contain a config file.

Workspace member exclusion with negation

Prefix a pattern with '!' to exclude directories that an earlier pattern would otherwise include. Both literal paths and glob patterns work after the '!'. This is useful when a wildcard sweep includes a directory you do not want as a workspace member.

Workspace dependency resolution process

When resolving imports from another workspace member, Deno follows these steps: (1) starts in the directory of the executing project, (2) looks up in parent directories for a root deno.json file, (3) checks for the 'workspace' property, (4) checks if the import matches a package name defined in any workspace member's deno.json, (5) verifies the containing directory is listed in the root workspace configuration, (6) resolves the import using the 'exports' field in the workspace member's deno.json.

Containerization requirements for workspace members

When containerizing a workspace member that depends on other workspace members, you must include: (1) the root deno.json file, (2) all dependent workspace packages, and (3) the same directory structure as the development environment. This preserves the workspace resolution mechanism that Deno uses to find and import workspace dependencies.

Package exports with single entry

The 'exports' property in a workspace member's deno.json specifies the entry point for importing that package. A single entry can be specified as a string value pointing to a module file, such as 'exports': './mod.ts'.

Package exports with multiple entries

The 'exports' property can be specified as an object to define multiple entry points for a package. Each key is an import specifier and each value is a path to a module file. The special '.' key represents the default entry that is picked when importing the package by name. For example, with 'exports': {'.': './mod.ts', './foo': './foo.ts', './other': './dir/other.ts'}, the importable entries are '@scope/my-package', '@scope/my-package/foo', and '@scope/my-package/other'.

Publishing workspace package to JSR

To publish a workspace package to JSR: (1) ensure each package has appropriate metadata in its deno.json including 'name', 'version', 'exports', and optionally 'publish' with 'exclude' array; (2) navigate to the specific package directory; (3) run 'deno publish'.

Excluding workspace member from deno publish

To opt out a workspace member from 'deno publish', set 'publish': false in that member's deno.json. The member remains part of the workspace, its tasks run, its imports are resolved, and other members can depend on it, but 'deno publish' skips it entirely. This only applies to deno.json members. Workspace members defined solely by package.json are npm packages and never candidates for 'deno publish'.

Publishing interdependent workspace packages

When publishing packages from a workspace with interdependencies, use consistent versioning schemes across related packages. Publish dependent packages first, then packages that depend on them. After publishing, verify the published packages work as expected. When publishing packages that depend on other workspace members, Deno will automatically replace workspace references with proper registry references in the published code.

Workspace member configuration inheritance

Workspace members inherit 'imports' from the workspace root, allowing single version management of a dependency across the entire codebase. Compiler options are inherited from root to member similar to TypeScript's TSConfig 'extends'.

Deno workspace configuration option matrix

Configuration options availability at workspace root vs package level: compilerOptions (✅/✅), importMap (✅/❌), imports (✅/✅), scopes (✅/❌), exclude (✅/✅), lint.include (✅/✅), lint.exclude (✅/✅), lint.files (⚠️/❌ deprecated), lint.rules.tags (✅/✅), lint.rules.include (✅/✅), lint.rules.exclude (✅/✅), lint.report (✅/❌), fmt.include (✅/✅), fmt.exclude (✅/✅), fmt.files (⚠️/❌ deprecated), fmt.useTabs (✅/✅), fmt.indentWidth (✅/✅), fmt.singleQuote (✅/✅), fmt.proseWrap (✅/✅), fmt.semiColons (✅/✅), fmt.options.* (⚠️/❌ deprecated), minimumDependencyAge (✅/❌), nodeModulesDir (✅/❌), vendor (✅/❌), allowScripts (✅/❌), links (✅/❌), tasks (✅/✅), test.include (✅/✅), test.exclude (✅/✅), test.files (⚠️/❌ deprecated), publish (❌/✅), publish.include (✅/✅), publish.exclude (✅/✅), bench.include (✅/✅), bench.exclude (✅/✅), bench.files (⚠️/❌ deprecated), lock (✅/❌), unstable (✅/❌), name (❌/✅), version (❌/✅), exports (❌/✅), workspace (✅/❌).

Running deno check across workspaces

Running 'deno check' from the workspace root will type-check all workspace members. Each member is partitioned and checked separately from one another. Workspace members can have different sets of compiler options that are inherited from the root.

Running tests across workspaces

To run tests across all workspace members, execute 'deno test' from the workspace root. This will run tests in all workspace members according to their individual test configurations. To run tests for a specific member, either change to that member's directory and run 'deno test', or specify the path from the workspace root with 'deno test my-directory/'.

Formatting and linting across workspaces

Running 'deno fmt' or 'deno lint' from the workspace root will format and lint all workspace members by default. Each member follows its own formatting and linting rules as defined in its deno.json file, with some settings inherited from the root configuration.

Workspace tasks execution

Tasks can be defined at both the workspace root and in individual workspace members in their deno.json files. To run a task defined in a specific package, use 'deno task --cwd=<package-name> <task-name>'. The cwd used is the cwd of the config file that the task was inside of.

Workspace member dependency overrides

When resolving dependencies, workspace members can override dependencies defined in the root. If both the root and a member specify different versions of the same dependency, the member's version will be used when resolving within that member's folder. Member-specific dependencies are scoped only to that member's folder. Outside of member folders or when working with files at the workspace root level, the workspace root's import map will be used for resolving dependencies.

Workspace protocol in package.json

Deno supports workspace protocol specifiers in package.json files for npm packages that depend on other packages within the workspace. Supported specifiers are: 'workspace:*' (use latest version available), 'workspace:~' (use workspace version with only patch-level changes), and 'workspace:^' (use workspace version with semver-compatible changes).

Centralized dependency versions with catalog protocol

The 'catalog:' protocol (added in Deno 2.8, compatible with pnpm, Bun, and Yarn) lets the workspace root declare a single version requirement for npm packages that multiple members depend on. A 'catalog:' reference can appear in a member's package.json dependencies or, since Deno 2.9, in the imports of a member's deno.json. The catalog definition itself lives in either deno.json or package.json at the workspace root.

Catalog protocol definition and usage

Define a catalog in the root deno.json with 'catalog': {package-name: version-requirement}. Members reference the entry with 'catalog:' (the default catalog) in their package.json dependencies. To bump a version for all members, edit the catalog once.

Named catalogs for different versions

Use the plural 'catalogs' field when different members need different versions of the same package. Members select a catalog by name with 'catalog:catalog-name'. This is useful while migrating between major versions.

Catalog limitations and restrictions

Catalogs are npm-only and every entry resolves to an 'npm:' package. JSR and other non-npm dependencies cannot be managed through a catalog. Catalogs are root-only and defining 'catalog' or 'catalogs' inside a workspace member emits a diagnostic. Members must reference a catalog name that exists; a missing entry produces a resolution error during install or run.

Catalog in package.json at workspace root

Catalogs can live in the root package.json, which keeps configuration together for projects that have not moved to deno.json. If both deno.json and package.json define catalogs at the workspace root, package.json wins entirely and the two are not merged.

npm workspace compatibility

Deno works seamlessly with standard npm workspaces defined in package.json with 'workspaces': [array of paths]. For pnpm users using a pnpm-workspace.yaml file, migration to a deno.json workspace configuration is required.

Migrating from pnpm-workspace.yaml to deno.json

pnpm-workspace.yaml configurations should be converted to deno.json format. A pnpm workspace with 'packages: [packages/*]' becomes 'workspace': ['packages/*'] in deno.json.

Workspace pattern matching support version

Pattern support for workspace member folders was added in Deno 2.1.

Deno workspace terminology

Deno uses 'workspace' (singular) to represent a single workspace with multiple members, rather than npm's 'workspaces' (plural).

Give your agent this brain