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 · all subjects

node and npm compatibility

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

CommonJS and ES module file type rules match Node.js

Deno determines module type using the same rules as Node.js: .cjs files are always CommonJS, .mjs files are always ES modules. For .js, .ts, .jsx, or .tsx files, the nearest package.json with "type": "commonjs" marks the file as CommonJS; otherwise it is treated as an ES module. Deno walks up the directory tree to find the package.json, just like Node.

Deno runs most Node.js projects unchanged

Most Node.js projects run in Deno with no changes at all. Deno reads package.json, installs and resolves the same npm dependencies, and runs both CommonJS and ES modules.

ReferenceError require is not defined means wrong module type

The error 'ReferenceError: require is not defined' indicates Deno treated the file as an ES module when it should be CommonJS. Set "type": "commonjs" in package.json or rename the file to .cjs.

Enable node_modules directory with nodeModulesDir auto

Set "nodeModulesDir": "auto" in deno.json to create a node_modules directory. This is required for CommonJS code and tools that expect the directory to exist.

Code without bun: or bun:* imports usually runs unchanged in Deno

Most Bun projects are standard package.json and TypeScript projects that Deno runs directly. Deno reads package.json, installs the same npm dependencies, and runs TypeScript without a build step. Code that imports nothing from bun or bun:* usually runs unchanged in Deno.

node:sqlite replaces bun:sqlite

Deno supports the node:sqlite built-in, which is synchronous and covers the same ground as bun:sqlite. Use DatabaseSync and StatementSync (instead of Database and Statement in Bun), but the prepare/run/get/all flow is the same.

deno.json replaces bunfig.toml for configuration

Runtime and tooling configuration moves from bunfig.toml to deno.json. Tasks, formatter and linter settings, compiler options, and import maps all live in deno.json. Deno reads package.json alongside deno.json, so you can migrate incrementally.

Bun features with no Deno equivalent

Macros: Bun can run functions at bundle time via with { type: "macro" } imports and inline the results. Deno has no bundle-time macro system; do that work in a build script instead. HTMLRewriter: Bun ships the Cloudflare Workers-compatible HTMLRewriter built on lol-html. Deno has no built-in HTMLRewriter global; use an npm package such as npm:lol-html or an HTML parser like deno-dom. Bundler specifics: bun build features like HTML entrypoints with automatic asset bundling do not map one-to-one onto the experimental deno bundle. For full-featured frontend builds, use Vite or another bundler under Deno.

deno install reads package.json and seeds deno.lock from bun.lock

When running deno install for the first time with no deno.lock present, Deno seeds the deno.lock file from an existing bun.lock file, carrying over the versions and integrity hashes already pinned. The bun.lock file is Bun's text lockfile (available since Bun 1.1.39); the legacy binary bun.lockb format is not read by Deno. If only bun.lockb exists, run bun install once to produce a bun.lock file, or allow Deno to resolve package.json ranges fresh.

pnpm to Deno run and execute command mapping

The following pnpm run and execute commands map to Deno equivalents: pnpm <script> → deno task <script>, pnpm run <script> → deno task <script>, pnpm dlx <pkg> → dx <pkg>, pnpm exec <cmd> → deno task <cmd>.

pnpm to Deno dependencies command mapping

The following pnpm package management commands map to Deno equivalents: pnpm install → deno install, pnpm add <pkg> → deno add <pkg>, pnpm add -D <pkg> → deno add -D <pkg>, pnpm remove <pkg> → deno remove <pkg>, pnpm update → deno update, pnpm outdated → deno outdated, pnpm install --frozen-lockfile → deno ci, pnpm audit → deno audit, pnpm why <pkg> → deno why <pkg>.

deno install behavior with pnpm-lock.yaml

When running deno install for the first time with no deno.lock file yet, Deno seeds the lockfile from an existing pnpm-lock.yaml file. The versions and integrity hashes already pinned carry over, preventing surprise version upgrades during migration.

Deno uses isolated node_modules layout like pnpm

Deno uses an isolated node_modules layout where each package only sees its declared dependencies, similar to pnpm's approach.

pnpm-workspace.yaml settings with no Deno equivalent

The following pnpm-workspace.yaml settings are pnpm-specific and have no Deno counterpart: overrides (force transitive dependency versions instead using npm: resolution or import maps), patchedDependencies (Deno has no built-in patch-package mechanism; vendor the dependency or maintain the patch in your own fork), registries, packageExtensions, and similar tuning (these configure pnpm's resolver specifically and do not carry over).

Deno is sandboxed by default

Deno is sandboxed by default. The first time a program touches the network, file system, or environment, Deno prompts for permission. To match Node's behavior and grant all permissions up front, run with deno run -A.

Deno reads workspaces field from package.json

Deno reads the workspaces field from package.json directly, the same as Yarn does. A monorepo configured with workspace globs like "workspaces": ["packages/*"] in package.json runs unchanged under Deno.

deno fmt and deno lint replace Prettier and ESLint

Deno ships with a formatter and linter built-in. deno fmt and deno lint replace Prettier and ESLint with no extra dependencies.

workspace: protocol for monorepo dependencies

Members of a monorepo reference each other through the workspace: protocol in their package.json dependencies, exactly as they do under Yarn. This works unchanged under Deno.

Peer dependencies and node_modules layout

In Deno's default isolated node_modules layout, each package only sees its declared dependencies, so peer dependencies must be explicitly provided by the project. Some npm tooling assumes the hoisted layout where dependencies are flattened to the top of node_modules. If a package walks node_modules looking for a peer as a sibling and cannot find it, switch to the hoisted linker by setting nodeModulesDir to manual and nodeModulesLinker to hoisted in deno.json.

Peer dependencies location in deno.json and package.json

Peer dependencies are an npm feature declared in package.json only. deno.json has no peerDependencies field and no equivalent. Deno reads peer dependencies from package.json files but does not support declaring them in deno.json.

How to provide a peer dependency in deno.json

To satisfy a peer dependency in a deno.json project, add both the package needing the peer and the peer dependency itself to the imports map. For example, if some-react-plugin declares react as a peer dependency, add both to imports: {"imports": {"react": "npm:react@^19", "some-react-plugin": "npm:some-react-plugin@^1"}}. This makes react resolvable in the dependency graph so the plugin can find it.

Optional peer dependencies with peerDependenciesMeta

A package can mark a peer dependency as optional using peerDependenciesMeta in its package.json. For example: {"peerDependencies": {"react": "^19"}, "peerDependenciesMeta": {"react": {"optional": true}}}. Optional peer dependencies only need to be provided if you use features that rely on them.

Fixing unmet peer dependencies errors

If a package's peer dependency is not present, importing it fails with a module-not-found error. To fix it, add the peer dependency to your project's dependencies and run deno install so the version is part of your dependency graph. If the package expects to find the peer as a hoisted sibling in node_modules, switch to the hoisted linker configuration.

GitHub personal access tokens for private repositories

To access private repositories on GitHub, create a personal access token via Settings -> Developer settings -> Personal access tokens on GitHub. The token should have the repo scope to enable reading file contents.

npm lifecycle scripts are opt-in

Unlike npm, Deno does not run `preinstall`/`postinstall` scripts by default because they are a common attack vector. To allow scripts for a package, use `deno install --allow-scripts=npm:package-name`. Scripts only execute when a `node_modules` directory is in use.

Why Deno doesn't have devImports

Deno does not separate dev dependencies in the package manifest because the runtime only loads and installs dependencies actually used in executing code. Dev dependencies are problematic in practice: it's easy to forget moving dependencies between `dependencies` and `devDependencies`, and many development-time packages like `@types/*` end up in `dependencies`. Deno offers two approaches instead: `deno install --prod` skips `devDependencies` from `package.json` and can also pass `--skip-types` to exclude `@types/*` packages; `deno install --entrypoint` installs only dependencies transitively imported by the specified entrypoint file, and combined with `--prod`, also excludes type-only dependencies.

HTTPS imports in Deno

Deno can import modules directly from `https:` URLs, either inline or mapped in `deno.json`. This suits small single-file scripts, but registries (JSR, npm) are recommended for applications. HTTPS imports can drift to different versions across files, are not managed by `deno add`/`deno install`, and trust the serving host. To pin and localize them, use vendoring.

JSR is the recommended registry for Deno packages

JSR is the recommended registry for Deno-first packages. It accepts TypeScript directly without a build step, generates documentation from JSDoc comments, and serves packages to Deno, Node.js, and other runtimes.

deno.land/x is the legacy registry

deno.land/x is the legacy registry for HTTPS imports. For new packages, JSR is preferred.

Updating dependencies intentionally workflow

To update dependencies intentionally: Temporarily allow lockfile writes by adding --frozen=false flag or setting "lock": { "frozen": false } in deno.json. Change versions (edit deno.json, use deno add <specifier>@<newVersion>, or remove with deno remove). Re-run deno install --entrypoint main.ts (optionally with --reload) to update resolutions and integrity hashes. Review the diff in deno.lock (and vendor/ if used) in your pull request. Re-enable the frozen lockfile.

Frozen lockfile error messages and fixes

Frozen lockfile errors include: 'The lockfile is frozen. Cannot add new entry for...' (cause: lockfile is in frozen mode, fix: re-run with --frozen=false or temporarily set "lock": { "frozen": false }, then update and re-freeze), 'Module not found in frozen lockfile' (cause: code now imports something not in lockfile, fix: unfreeze with --frozen=false and run deno install --entrypoint <entry>.ts), removed imports but lockfile still contains old entries (cause: lockfile is additive, fix: optionally regenerate by moving deno.lock aside and recreating), lockfile corruption/merge conflict (cause: manual edit or conflict left inconsistent JSON, fix: delete conflicting sections and re-run install, or regenerate), vendor dir out of sync with lockfile (cause: using vendored deps but lockfile complains, fix: re-run deno install --entrypoint <entry> unfrozen to sync both).

Safe lockfile regeneration checklist

Only regenerate the entire deno.lock when necessary (corruption, massive pruning). When regenerating: Back it up with cp deno.lock deno.lock.bak. Remove it with rm deno.lock. If vendoring, remove or move the vendor/ directory. Run deno install --entrypoint main.ts to recreate. Inspect the diff between old and new to catch unexpected additions.

Lockfile and vendor directory complementary usage

Lockfile and vendor directory are complementary: Lockfile records exact resolved versions and integrity hashes for remote and npm/JSR deps. Vendor directory stores the actual source locally for hermetic, offline, and patchable builds. Use both for maximum reproducibility. A frozen lockfile alone does not make your build fully hermetic if the remote source disappears; vendoring closes that gap.

Automated weekly dependency refresh pattern

A scheduled CI job that unfreezes the lockfile, runs deno add --latest (or manually bumps key packages), executes tests, and opens a pull request with the updated deno.lock (and vendor/) keeps security patches flowing while keeping day-to-day builds deterministic.

Quick decision guide for supply chain needs

Detect upstream tampering: use lockfile (commit & freeze). Offline/air-gapped build: use vendor: true with lockfile. Patch third-party code: use vendoring or scopes overrides (short-term). Fast CI with integrity: use deno install --frozen. Intentionally upgrade: temporarily unfreeze, run install, review diff. Block a publishing-trust downgrade: use trust-policy=no-downgrade in .npmrc.

Supply chain management goals

Modern JavaScript projects should pursue four supply chain management goals: determinism (everyone runs the exact same code), security (unexpected upstream changes or compromises are detected early), velocity (you can update dependencies intentionally when you choose), and resilience (builds keep working offline or when registries have outages).

Core supply chain practices

Core supply chain practices include: Pin versions deliberately (exact versions for applications, caret ranges for libraries, avoid unbounded ranges in production). Commit your deno.lock file. Enable a frozen lockfile in CI/production using --frozen flag or "lock": { "frozen": true } in deno.json so new dependencies fail the build. Vendor when you need hermetic/offline builds using "vendor": true or when you must patch third-party code locally. Use jsr: and npm: specifiers with import map (imports) entries to centralize version management. Periodically unfreeze and update consciously on a scheduled cadence instead of ad-hoc updates. Set a minimum dependency age so freshly published versions can't slip into installs. Turn on a publishing-trust policy so weaker publishing methods are rejected.

Minimum dependency age default in Deno 2.9

Since Deno 2.9, minimum dependency age is on by default with a 24-hour window. Versions published in the last day are skipped even with no configuration.

Publishing-trust policy levels

Publishing-trust policy has five trust levels ranked from least to most trusted: Plain (no publishing-trust signal), Provenance (provenance attestation only), Trusted publishing (OIDC trusted publisher only), Trusted publishing + provenance (both of the above), and Staged (human-approved staged publish with live 2FA challenge, ranks above all). Deno records the resolved trust level on each npm entry in deno.lock with a trust field (omitted when the version is plain).

Enable publishing-trust policy no-downgrade

Enable the publishing-trust policy no-downgrade in .npmrc with trust-policy=no-downgrade. When enabled, Deno refuses to resolve any candidate version whose trust level is below the locked baseline for that package, protecting against supply-chain attacks where a stolen token is used to publish versions with weaker publishing methods.

Give your agent this brain