|
1 | 1 | --- |
2 | 2 | last_modified: 2026-06-08 |
3 | 3 | title: "Migrating from Node.js to Deno" |
4 | | -description: "How to migrate an existing Node.js project to Deno: most projects run unchanged. Covers the rare compatibility points, running npm scripts with deno task, adopting Deno's toolchain, and a Node-to-Deno command cheatsheet." |
| 4 | +description: "How to move a Node.js project to Deno: use Deno as a drop-in package manager, run your existing project and package.json scripts, understand how CommonJS and ES modules are resolved, and map your Node commands to Deno." |
5 | 5 | oldUrl: |
6 | 6 | - /runtime/manual/node/migrate/ |
7 | 7 | - /runtime/manual/references/cheatsheet/ |
8 | 8 | - /runtime/manual/node/cheatsheet/ |
9 | 9 | --- |
10 | 10 |
|
11 | | -Most Node.js projects run in Deno **with no changes at all**. Point Deno at your |
12 | | -entry file or your `package.json` scripts and it just works: Deno reads |
13 | | -`package.json`, resolves your npm and `node:` dependencies, and runs both ES |
14 | | -modules and CommonJS out of the box. |
| 11 | +Most Node.js projects run in Deno **with no changes at all**. Deno reads your |
| 12 | +`package.json`, installs and resolves the same npm dependencies, runs both |
| 13 | +CommonJS and ES modules, and exposes Node's built-in modules through `node:` |
| 14 | +specifiers — so in most cases you point Deno at your existing project and it |
| 15 | +just works. |
| 16 | + |
| 17 | +You can also adopt Deno incrementally: use it purely as a faster, drop-in |
| 18 | +package manager for an app you still run with Node, run your existing |
| 19 | +`package.json` scripts with `deno task`, or switch to Deno as the runtime and |
| 20 | +pick up its built-in toolchain. This guide walks through each step. |
| 21 | + |
| 22 | +## Use Deno as your package manager |
| 23 | + |
| 24 | +Deno is fully compatible with npm and `package.json`, so the easiest place to |
| 25 | +start is dependency management — without changing how you run your code at all. |
| 26 | +`deno install` reads your existing `package.json`, resolves the same npm |
| 27 | +packages, and writes a `node_modules` directory, just like `npm install`: |
15 | 28 |
|
16 | 29 | ```sh |
17 | | -# An existing Node project — no migration step required |
18 | | -deno run main.js |
19 | | -deno task start |
| 30 | +cd my-node-app |
| 31 | +deno install |
| 32 | +``` |
| 33 | + |
| 34 | +You can keep running the app with Node from here — using Deno only as a faster |
| 35 | +package manager — or manage dependencies with Deno's built-in commands: |
| 36 | + |
| 37 | +```sh |
| 38 | +deno add npm:express # add a dependency |
| 39 | +deno remove express # remove one |
| 40 | +deno outdated # see what has newer versions |
20 | 41 | ``` |
21 | 42 |
|
22 | | -The main thing to be aware of is CommonJS interop: it's well supported but |
23 | | -doesn't cover every situation. `require()` is available in `.cjs` files or via |
24 | | -`createRequire`, and you can mix CommonJS and ES modules — see |
25 | | -[CommonJS support](/runtime/fundamentals/node/#commonjs-support) for the cases |
26 | | -that need attention. |
| 43 | +Deno understands dependencies declared in both `package.json` and `deno.json`, |
| 44 | +and individual npm packages can also be imported inline with `npm:` specifiers. |
| 45 | +See [Modules and dependencies](/runtime/fundamentals/modules/) for the full |
| 46 | +picture. |
27 | 47 |
|
28 | | -For the complete picture of what's supported, see |
29 | | -[Node and npm compatibility](/runtime/fundamentals/node/). |
| 48 | +## Run your project with Deno |
30 | 49 |
|
31 | | -## Running scripts |
| 50 | +To run an existing Node project with Deno, install its dependencies and run the |
| 51 | +entrypoint: |
| 52 | + |
| 53 | +```sh |
| 54 | +cd my-node-app |
| 55 | +deno install |
| 56 | +deno run main.js |
| 57 | +``` |
32 | 58 |
|
33 | | -Deno supports running npm scripts natively with the |
34 | | -[`deno task`](/runtime/reference/cli/task/) subcommand (If you're migrating from |
35 | | -Node.js, this is similar to the `npm run script` command). Consider the |
36 | | -following Node.js project with a script called `start` inside its |
37 | | -`package.json`: |
| 59 | +If your `package.json` defines scripts, run them with |
| 60 | +[`deno task`](/runtime/reference/cli/task/) — the equivalent of `npm run`: |
38 | 61 |
|
39 | 62 | ```json title="package.json" |
40 | 63 | { |
41 | 64 | "name": "my-project", |
42 | 65 | "scripts": { |
43 | | - "start": "eslint" |
| 66 | + "start": "node server.js" |
44 | 67 | } |
45 | 68 | } |
46 | 69 | ``` |
47 | 70 |
|
48 | | -You can execute this script with Deno by running: |
49 | | - |
50 | 71 | ```sh |
51 | 72 | deno task start |
52 | 73 | ``` |
53 | 74 |
|
| 75 | +Most code runs unchanged. The main thing to understand is how Deno decides |
| 76 | +whether a file is CommonJS or an ES module, which follows your `package.json` — |
| 77 | +covered next. |
| 78 | + |
| 79 | +## CommonJS and ES modules |
| 80 | + |
| 81 | +Deno runs both ES modules and CommonJS, and decides how to treat a file using |
| 82 | +the same rules as Node.js: |
| 83 | + |
| 84 | +- A `.cjs` file is **always** CommonJS, and a `.mjs` file is **always** an ES |
| 85 | + module — the extension is enough. |
| 86 | +- A `.js`, `.ts`, `.jsx`, or `.tsx` file is loaded as **CommonJS** when the |
| 87 | + nearest `package.json` sets `"type": "commonjs"`, and as an **ES module** |
| 88 | + otherwise. Deno walks up the directory tree to find that `package.json`, just |
| 89 | + like Node. |
| 90 | + |
| 91 | +```json title="package.json" |
| 92 | +{ |
| 93 | + "type": "commonjs" |
| 94 | +} |
| 95 | +``` |
| 96 | + |
| 97 | +So an existing CommonJS project keeps working: with `"type": "commonjs"` in |
| 98 | +`package.json`, your `require()`-based `.js` files run under both Node and Deno. |
| 99 | +CommonJS code needs its dependencies present in `node_modules` (set |
| 100 | +`"nodeModulesDir": "auto"` in `deno.json`) and the usual |
| 101 | +[permission flags](/runtime/fundamentals/security/). |
| 102 | + |
| 103 | +You can also mix the two module systems: `require()` is available in `.cjs` |
| 104 | +files or via `createRequire`, Deno's `require()` can load synchronous ES |
| 105 | +modules, and you can `import` CommonJS files from ES modules. See |
| 106 | +[CommonJS support](/runtime/fundamentals/node/#commonjs-support) for the details |
| 107 | +and edge cases. |
| 108 | + |
54 | 109 | ## Node to Deno Cheatsheet |
55 | 110 |
|
56 | 111 | In a Node project, many of these are separate packages you install and configure |
|
0 commit comments