> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/oven-sh/bun/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating from Node.js

> Replace Node.js with Bun as a drop-in runtime. Most projects require only a few command substitutions and no code changes.

Bun is designed to be a drop-in replacement for Node.js. It implements nearly the same set of APIs, runs `.js`, `.ts`, `.jsx`, and `.tsx` files natively, and is compatible with the npm ecosystem. Most projects work with Bun after a handful of command substitutions.

## Step-by-step migration

<Steps>
  <Step title="Install Bun">
    Install Bun on macOS, Linux, or Windows:

    ```bash theme={null}
    # macOS and Linux
    curl -fsSL https://bun.sh/install | bash

    # Windows
    powershell -c "irm bun.sh/install.ps1 | iex"
    ```

    Verify the installation:

    ```bash theme={null}
    bun --version
    ```
  </Step>

  <Step title="Replace npm scripts with Bun equivalents">
    The most common command substitutions:

    | Node.js / npm          | Bun                                  |
    | ---------------------- | ------------------------------------ |
    | `npm install`          | `bun install`                        |
    | `npm install <pkg>`    | `bun add <pkg>`                      |
    | `npm install -D <pkg>` | `bun add -d <pkg>`                   |
    | `npm uninstall <pkg>`  | `bun remove <pkg>`                   |
    | `npm run <script>`     | `bun run <script>` or `bun <script>` |
    | `node <file>`          | `bun <file>`                         |
    | `npx <package>`        | `bunx <package>`                     |

    Update the `scripts` in your `package.json` to use Bun:

    ```json package.json theme={null}
    {
      "scripts": {
        "dev": "bun run src/index.ts",
        "build": "bun build src/index.ts --outdir dist",
        "test": "bun test"
      }
    }
    ```
  </Step>

  <Step title="Run bun install">
    Replace your existing lockfile with Bun's:

    ```bash theme={null}
    bun install
    ```

    Bun automatically converts `package-lock.json` or `yarn.lock` to `bun.lock`, preserving your existing resolved dependency versions.
  </Step>

  <Step title="Replace node with bun in CI/CD scripts">
    In GitHub Actions or other CI systems, substitute `node` and `npm` with `bun`:

    ```yaml .github/workflows/ci.yml theme={null}
    - uses: oven-sh/setup-bun@v2
      with:
        bun-version: latest

    - run: bun install
    - run: bun test
    - run: bun run build
    ```
  </Step>
</Steps>

## TypeScript support

Bun runs TypeScript natively — no `ts-node`, `tsx`, or compilation step required. For type checking, install `@types/bun`:

```bash theme={null}
bun add -d @types/bun
```

Use this recommended `tsconfig.json` for Bun projects:

```json tsconfig.json theme={null}
{
  "compilerOptions": {
    "lib": ["ESNext"],
    "target": "ESNext",
    "module": "Preserve",
    "moduleDetection": "force",
    "jsx": "react-jsx",
    "allowJs": true,
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "verbatimModuleSyntax": true,
    "noEmit": true,
    "strict": true,
    "skipLibCheck": true,
    "types": ["bun"]
  }
}
```

## Node.js globals

The following Node.js globals work in Bun without changes:

```typescript theme={null}
// Environment variables
process.env.MY_VAR;
Bun.env.MY_VAR; // Bun-native alias

// Buffer
const buf = Buffer.from("hello", "utf8");
buf.toString("base64");

// __dirname and __filename (CommonJS)
console.log(__dirname);
console.log(__filename);

// import.meta (ESM equivalent)
console.log(import.meta.dir);   // equivalent to __dirname
console.log(import.meta.file);  // equivalent to __filename

// process
process.exit(0);
process.argv;
process.cwd();
```

## CommonJS and ESM

Bun supports both CommonJS (`require`) and ESM (`import`) in the same project. You do not need to add `"type": "module"` to `package.json` — Bun infers the module format from the file extension and `package.json` fields:

```typescript theme={null}
// ESM (preferred)
import { readFile } from "fs/promises";
import data from "./data.json";

// CommonJS also works
const { readFileSync } = require("fs");
```

<Note>
  When mixing CJS and ESM in the same file, Bun follows the same rules as Node.js. `.mjs` files are always ESM; `.cjs` files are always CommonJS.
</Note>

## npm package compatibility

Virtually all packages from the npm registry work with Bun. Packages that rely on Node.js built-in modules (`fs`, `path`, `crypto`, `http`, etc.) are supported via Bun's Node.js compatibility layer.

A small number of packages that use native Node.js add-ons (`.node` files compiled with node-gyp) may not work. Check the [Bun Node.js compatibility page](https://bun.sh/docs/runtime/nodejs-compat) for a full list of supported APIs.

## Common gotchas

<AccordionGroup>
  <Accordion title="Packages with #!/usr/bin/env node shebang">
    By default, Bun respects the `node` shebang and uses the system's Node.js executable. To force Bun's runtime, pass `--bun`:

    ```bash theme={null}
    bun --bun my-script
    ```
  </Accordion>

  <Accordion title="Dynamic require() in ESM files">
    If you see `require is not defined` errors, the file is being treated as ESM. Either rename the file to `.cjs` or convert to `import` syntax.
  </Accordion>

  <Accordion title="Missing process.env values">
    Bun loads `.env` files automatically. You do not need `dotenv`. If a variable is missing, ensure the `.env` file is in the project root or use `Bun.env`.
  </Accordion>

  <Accordion title="node_modules resolution">
    Bun uses Node.js module resolution by default. If a package is not found, run `bun install` to ensure all dependencies are present.
  </Accordion>
</AccordionGroup>
