# Migrate from Node.js

Deno 2 can run many existing Node projects. The goal is not to rewrite every import at once; it is to accumulate reversible compatibility evidence.

## Incremental adoption

1. Pin Deno and record `deno --version` in the existing branch.
2. Keep `package.json`, the current lockfile, and the existing `node_modules` strategy; run one side-effect-free script first.
3. Execute current tests and classify failures in Node APIs, native addons, loaders, and lifecycle scripts.
4. Introduce `deno.json` tasks and run Deno commands beside current commands.
5. Remove old tools or lockfiles only after CI, developer, and production verification.

## Compatibility conventions

```ts
import { readFile } from "node:fs/promises";
import express from "npm:express";
```

Deno can also resolve common bare npm imports from `package.json`. Whether a local `node_modules` is enabled or required depends on project configuration and dependency behavior; one mode does not fit every package.

## High-risk areas

- Node-API addons, postinstall scripts, and binary downloads;
- custom ESM loaders, resolution hacks, and implicit extensions;
- Jest/Vitest globals, fake timers, and snapshot differences;
- undeclared environment, filesystem, and network access;
- edge behavior in `process`, Buffer, streams, and Node APIs.

<Callout type="warn" title="Replace one layer at a time">
Do not change runtime, test framework, package manager, formatting rules, and deployment platform in one migration commit. Failures become impossible to attribute.
</Callout>

Official references: [Node compatibility](https://docs.deno.com/runtime/fundamentals/node/) and [Migrate to Deno](https://docs.deno.com/runtime/migrate/).
