# Migrate To Deno

> Use when moving a Node.js, npm, Yarn, pnpm, or Bun project to Deno, or when adopting Deno incrementally in an existing JavaScript or TypeScript codebase. Covers using Deno as a drop-in package manager, running existing package.json scripts, CommonJS versus ESM, node_modules layout, lockfile migration, permissions, whether to adopt the built-in toolchain, and per-tool command equivalents.

- **Type:** Skill
- **Install:** `agentstack add skill-denoland-skills-migrate-to-deno`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [denoland](https://agentstack.voostack.com/s/denoland)
- **Installs:** 0
- **Category:** [Developer Tools](https://agentstack.voostack.com/c/developer-tools)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [denoland](https://github.com/denoland)
- **Source:** https://github.com/denoland/skills/tree/main/skills/migrate-to-deno

## Install

```sh
agentstack add skill-denoland-skills-migrate-to-deno
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Migrating to Deno

Requires Deno 2.9 or later. For general Deno usage once migrated, see the `deno`
skill.

## Most Node projects already run under Deno

Deno reads an existing `package.json`, resolves the same npm packages, writes a
real `node_modules`, runs the same scripts, and supports `node:` built-ins.
TypeScript runs with no build step.

There is usually **no code to change** — only which binary you invoke. Don't
start by rewriting imports to `jsr:`, swapping dependencies for Deno-specific
ones, or restructuring directories. Proposing that is the most common way this
goes wrong.

## Migrate in rungs

Each rung is independently useful and reversible. Stop wherever suits the
project; plenty of teams stop at rung 1.

### Rung 1 — Deno as the package manager only

```bash
deno install
```

Reads `package.json`, resolves the same dependencies, writes `node_modules`, and
creates `deno.lock` — seeded from any existing `package-lock.json`, `yarn.lock`,
`bun.lock`, or pnpm lockfile, so pins and integrity hashes carry over instead of
drifting.

The app still runs under `node`; teammates are unaffected. Commit `deno.lock`
once verified. **To back out:** delete `deno.lock` and `node_modules`, then
`npm install`.

### Rung 2 — Run it with Deno

```bash
deno run -A main.js      # or: deno -A main.js
deno task build          # runs scripts.build from package.json
```

Use `-A` here. The goal is confirming the program works, not designing a
permission policy — changing both at once makes failures ambiguous.

### Rung 3 — Tighten permissions

Replace `-A` with the narrowest set that works: run it, read what it asks for,
grant exactly that.

```bash
deno run --allow-net=api.example.com --allow-read=./config --allow-env=PORT main.js
```

This buys something Node cannot offer, and is worth doing before deploying.

### Rung 4 — Optionally, adopt the built-in toolchain

`deno fmt` for prettier, `deno lint` for eslint, `deno test` for jest or vitest,
`deno check` for tsc, `deno watch` for nodemon, `deno compile` for pkg.

**Optional, and usually not worth it for an existing project.** These are not
drop-in replacements; parity is incomplete, so this is a real migration, not a
config change. A project happy with prettier, eslint, and vitest should keep
them and use Deno as runtime and package manager only. Prefer the built-in tools
for new projects. If you do move an existing one, go a tool at a time.

## Command equivalents

| Task          | npm                 | Yarn                        | pnpm                       | Bun                             | Deno              |
| ------------- | ------------------- | --------------------------- | -------------------------- | ------------------------------- | ----------------- |
| Install all   | `npm install`       | `yarn install`              | `pnpm install`             | `bun install`                   | `deno install`    |
| Add           | `npm i `         | `yarn add `              | `pnpm add `             | `bun add `                   | `deno add `    |
| Add dev       | `npm i -D `      | `yarn add -D `           | `pnpm add -D `          | `bun add -d `                | `deno add -D ` |
| Remove        | `npm uninstall ` | `yarn remove `           | `pnpm remove `          | `bun remove `                | `deno remove ` |
| CI install    | `npm ci`            | `yarn install --immutable`† | `pnpm i --frozen-lockfile` | `bun install --frozen-lockfile` | `deno ci`         |
| Run script    | `npm run `       | `yarn `                  | `pnpm `                 | `bun run `                   | `deno task `   |
| Run binary    | `npx `           | `yarn dlx `              | `pnpm dlx `             | `bunx `                      | `dx `          |
| Outdated      | `npm outdated`      | `yarn outdated`‡            | `pnpm outdated`            | `bun outdated`                  | `deno outdated`   |
| Audit         | `npm audit`         | `yarn npm audit`†           | `pnpm audit`               | `bun audit`                     | `deno audit`      |
| Why           | `npm ls `        | `yarn why `              | `pnpm why `             | `bun why `                   | `deno why `    |
| Run a file    | `node f.js`         |                             |                            | `bun f.ts`                      | `deno f.ts`       |
| Run TS        | `ts-node f.ts`      |                             |                            | `bun f.ts`                      | `deno f.ts`       |
| Watch         | `nodemon f.js`      |                             |                            | `bun --watch f.ts`              | `deno watch f.ts` |
| Format        | prettier            |                             |                            | prettier                        | `deno fmt`        |
| Lint          | eslint              |                             |                            |                                 | `deno lint`       |
| Test          | jest, vitest        |                             |                            | `bun test`                      | `deno test`       |
| Coverage      | nyc, c8             |                             |                            |                                 | `deno coverage`   |
| Type-check    | `tsc --noEmit`      |                             |                            | `tsc`                           | `deno check`      |
| Bundle binary | pkg, nexe           |                             |                            | `bun build --compile`           | `deno compile`    |

† Yarn Berry (v2+) spelling. Yarn Classic (v1) uses
`yarn install --frozen-lockfile` and `yarn audit`.

‡ Yarn Classic only — Berry removed `yarn outdated`.

`dx` is a separate binary installed alongside Deno, and an alias for `deno x`.
It does not appear in the top-level `deno --help` output. Like `npx`, it runs
the package with the sandbox disabled.

## The four things that actually break

### `Requires net access to "..."` (or read, env, run)

Deno grants nothing by default. Add that specific permission, or `-A` while
still establishing the program works at all.

### `ReferenceError: require is not defined`

A file containing CommonJS is being parsed as ESM. `.cjs` is always CommonJS,
`.mjs` always ESM; `.js` and `.ts` follow `"type"` in the nearest
`package.json`. For a CommonJS project, set `"type": "commonjs"`.

### A dependency is broken, or `postinstall` never ran

Lifecycle scripts don't run by default. Native addons notice immediately.
Approvals are recorded in the config file, so this is one-time:

```bash
deno approve-scripts                              # interactive picker
deno install --allow-scripts=npm:better-sqlite3   # or name them directly
```

### A tool cannot find files inside `node_modules`

Deno's layout is pnpm-style: real files in `node_modules/.deno/`, exposed via
symlinks. Tools assuming npm's flat hoisted tree need:

```json
{ "nodeModulesLinker": "hoisted" }
```

## What has no Deno equivalent

Say so rather than improvising a workaround that won't hold:

- **Yarn Plug'n'Play.** Deno creates a real `node_modules`; `.pnp.cjs` is unused
  and `.yarnrc.yml` resolver settings don't transfer.
- **`yarn patch` / pnpm patched dependencies.** Vendor or fork.
- **`overrides` / `resolutions`.** Pin via an import map entry instead.
- **Registry and resolver tuning** in `.npmrc` / `.yarnrc.yml`.
- **Bun build features** — macros, HTMLRewriter, HTML entrypoints.

## Per-tool details

- `references/FROM_NPM.md` — lockfile seeding, `node_modules` layout, overrides
- `references/FROM_YARN.md` — Plug'n'Play, Berry vs Classic, workspaces
- `references/FROM_PNPM.md` — `pnpm-workspace.yaml`, `catalog:`, patches
- `references/FROM_BUN.md` — Bun API translation, `bunfig.toml`
- `references/NODE_APIS.md` — `node:` built-ins, `DENO_COMPAT`, CJS/ESM

## Further reading

-  — official migration guides
-  — Node and npm
  compatibility
-  — per-module Node API
  status

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [denoland](https://github.com/denoland)
- **Source:** [denoland/skills](https://github.com/denoland/skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-denoland-skills-migrate-to-deno
- Seller: https://agentstack.voostack.com/s/denoland
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
