Skip to main content
Extension.js treats Deno as a first-class runtime, and a CI lane runs extension build and extension dev on Deno for every change. Scaffold with Deno and the project gets a deno.jsonc instead of a package.json. Work in a hybrid project and deno.jsonc sits beside package.json for Deno-native settings. Either way, extension dev and extension build behave the same.

Which Deno versions work

Extension.js needs Deno 2.5 or newer. The CLI reads process.versions.deno at startup and judges Deno on its own version, never on the Node version that Deno emulates, so the number in the message is the one you can act on.

Create a project with Deno

Then run the dev task:

Primary mode: deno.jsonc is the project manifest

When you scaffold under the Deno runtime, deno.jsonc becomes the project’s only manifest and package.json is removed.
  • Template dependencies move into imports as npm: specifiers, and deno install resolves them.
  • The extension engine itself is declared there too, as npm:extension@<version>.
  • nodeModulesDir is set to "auto", so npm: dependencies materialize in a real node_modules directory. The bundler resolves project dependencies from it at dev and build time.
  • deno task <name> also finds binaries in node_modules/.bin, so the generated tasks run the locally installed Extension.js CLI.
A trimmed example:
When a template ships its own Deno config, Extension.js merges into that file instead of creating a second one. Deno’s own discovery prefers deno.json over deno.jsonc, so the merge targets the file that Deno will read.

Companion mode: deno.jsonc beside package.json

Monorepo templates, and projects that already have a package.json, keep it. Dependencies stay declared in package.json, and deno install resolves them from there. The companion deno.jsonc carries only Deno-native settings and the tasks that run the CLI.

How the toolchain detects Deno

Detection works on files, not on how you invoked the CLI:
  • Extension.js reads deno.jsonc or deno.json when it scans project dependencies. Framework, CSS, and TypeScript detection all see packages that imports declares through npm: specifiers.
  • When both manifests declare the same package, the package.json entry wins.
  • A project counts as Deno-managed when it has a deno.lock, or a Deno config with no package.json beside it. An npm-family lockfile wins for hybrids, and Deno is claimed only when the deno binary is on your PATH.

TypeScript in Deno projects

TypeScript detection follows the same rules as everywhere else. See TypeScript: SWC compiles the sources, and the typescript package is only needed for tsc --noEmit.

Managed browsers need Node.js

extension install <browser> downloads a managed browser through npx, or through the package manager that launched the CLI. deno has no such runner, so on Deno that one command needs Node.js on your PATH. Without it the command fails at the download step. dev, build, preview, and start run on Deno alone, and a browser that is already installed on your system needs no download. See install.

Next steps