Node.js compability mode

Starting with v1.15 Deno provides Node compatiblity mode that makes it possible to run a subset of programs authored for Node.js directly in Deno. Compatiblity mode can be activated by passing --compat flag in CLI.

⚠️ Using compatiblity mode currently requires the --unstable flag. If you intend to use CJS modules, the --allow-read flag is needed as well.

⚠️ Package management is currently out of scope for Node.js compatiblity mode. For the time being we suggest to keep using your current solution (npm, yarn, pnpm).

Example

eslint is a very popular tool used by most of Node.js projects. Let's run eslint using Deno in Node.js compatiblity mode. Assuming that eslint is already installed locally (either using npm install eslint or yarn install eslint) we can do so like:

$ ls
.eslintrc.json
node_modules
package.json
test.js
test.ts
$ cat test.js
function foo() {}

$ cat test.ts
function bar(): any {}

$ deno run \
  --compat --unstable \
  --allow-read --allow-write=./ --allow-env \
  node_modules/eslint/bin/eslint.js test.js test.ts

/dev/test.js
  1:10  warning  'foo' is defined but never used  @typescript-eslint/no-unused-vars
  1:16  error    Unexpected empty function 'foo'  @typescript-eslint/no-empty-function

/dev/test.ts
  1:10  warning  'bar' is defined but never used           @typescript-eslint/no-unused-vars
  1:17  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any
  1:21  error    Unexpected empty function 'bar'           @typescript-eslint/no-empty-function

✖ 5 problems (2 errors, 3 warnings)

⚠️ Notice that ESLint is run with limited set of permissions. We only give it access to the read from the file system, write to current directory and access environmental variables. Programs run in compatility mode are subject to Deno's permission model.

How does it work?

When using compatibility mode there Deno does a few things behind the scenes:

specifiers will work. For details on how module resolution works check Node documentation on CJS and ES modules.

Module resolution

CommonJS resolution is implemented as in Node.js and there should be no observable differences.

ES module resolution is implemented on top of Deno's regular ESM resolution, leading to a few additional properties compared to Node.js:

"Conditional exports" field in package.json; in addition to conditions recognized by Node.js, "deno" condition can be used. This property is useful to the package authors who want to provide separate entrypoint optimized for use with Deno. As an example, imagine that your package uses node-fetch. By providing a conditional "deno" export, you can add an entrypoint that doesn't depend on node-fetch and instead uses built-in fetch API in Deno.

Node.js built-in modules

Following built-in Node modules are currently supported:

Following modules are not yet implemented:

If you try to run Node code that requires any of the not implemented modules, please open an issue in https://github.com/denoland/deno_std/issues with example code.

TypeScript support

Currently, the compability mode does not support TypeScript.

In the upcoming releases we plan to add support for a types field in package.json, to automatically lookup types and use them during type checking.

In the long term, we'd like to provide ability to consume TypeScript code authored for the Node.js runtime.