# Migrate from Hardhat 2

Description: How to migrate from Hardhat 2 to Hardhat 3

Note: This document was authored using MDX

  Source: https://github.com/NomicFoundation/hardhat-website/tree/main/src/content/docs/docs/migrate-from-hardhat2/index.mdx

  Components used in this page:
    - <Run cmd="..."/>: Runs a command in the terminal with npm/pnpm/yarn.
    - <Install pkg="..."/>: Installs a package in the terminal with npm/pnpm/yarn.
    - <Tabs>: Tabbed content sections. Props: `syncKey` to synchronize tab selection across multiple tab groups.
    - <TabItem>: A tab within <Tabs>. Props: `label`, `icon`.
    - <Code>: Expressive Code component for programmatic code blocks. Props: `code`, `lang`, `title`, `mark`, etc.
    - :::tip: A helpful tip callout block. Supports custom title `:::tip[Title]` and icon `:::tip{icon="name"}` syntax.

import { TabItem, Tabs } from "@astrojs/starlight/components";
import { Code } from "@astrojs/starlight/components";
import Install from "@hh/Install.astro";
import Run from "@hh/Run.astro";

:::tip

Hardhat 3 is production-ready and you can migrate today! We'll keep it in beta status as we work on missing features and stabilize it in the near future.

:::

Hardhat 3 is a complete rewrite of Hardhat 2. While many features are familiar, several fundamental changes mean the new version isn't directly compatible with Hardhat 2 projects:

- **ESM-first**: Your Hardhat config must be an ES module. Scripts and JavaScript/TypeScript tests can still be CommonJS, but ESM is the default.
- **Declarative config**: Plugins, tasks, and other extensions are configured explicitly in your config instead of being registered by side effects.
- **Explicit network connections**: You create and manage [network connections](/docs/explanations/network-management) yourself, allowing multiple concurrent connections in one process, but meaning that `hre.network` no longer represents a single network connection that is immediately available.
- **Extensibility through hooks**: Features like `extendConfig` and subtask overriding were replaced by the new [hooks system](/docs/plugin-development/explanations/hooks). Adding new fields to the Hardhat Runtime Environment with `extendEnvironment` is no longer possible, but the typical use cases for extending it can be covered by other mechanisms.

Because these changes are significant, this guide recommends starting with a clean config and migrating features step by step, rather than trying to adapt an Hardhat 2 project in place.

## Before starting the migration

Before making any changes, prepare your project so that installing and running Hardhat 3 won’t conflict with leftover dependencies, configs, or build artifacts from Hardhat 2.

1.  **Check node.js version**

    Make sure you are using Node.js v22.10.0 or later:

    ```sh
    node --version
    ```

2.  **Clear caches and artifacts**

    Run the `clean` task to avoid issues with stale artifacts or caches:

    <Run command="hardhat clean" />

3.  **Remove Hardhat 2 dependencies**

    Start by removing these packages from your `package.json`:
    - `hardhat`
    - Any packages starting with `hardhat-`, `@nomicfoundation/`, or `@nomiclabs/`
    - `solidity-coverage` and `hardhat-gas-reporter`

    Then reinstall and check for remaining packages that depend on Hardhat:

    <Run command={["install", "why hardhat"]} />

    Repeat until no Hardhat-related dependencies remain.

4.  **Rename your old config**

    Keep your old config for reference, but rename it so you can create a new one alongside it:

    ```sh
    mv hardhat.config.js hardhat.config.old.js
    ```

5.  **Make your project ESM**

    {/* prettier-ignore */}
    <Tabs syncKey="package-manager">
      <TabItem label="npm" icon="npm">
        <Code code="npm pkg set type=module" lang="sh" frame="terminal" />
      </TabItem>
      <TabItem label="pnpm" icon="pnpm">
        <Code code="pnpm pkg set type=module" lang="sh" frame="terminal" />
      </TabItem>
      <TabItem label="Yarn" icon="seti:yarn">
        <Code code={`# yarn doesn't have a command for this\nnpm pkg set type=module`} lang="sh" frame="terminal" />
      </TabItem>
    </Tabs>

6.  **(Optional) Adapt your `tsconfig.json`**

    If you have a `tsconfig.json` file, make sure that `compilerOptions.module` is set to an ESM-compatible value like `"node16"`.

## Setting up Hardhat 3

With your npm project ready, you can start setting up Hardhat 3.

1. **Install Hardhat 3**

   Run the following command to install Hardhat 3:

   <Install packages="hardhat" />

2. **Create an empty config file**

   Create a `hardhat.config.ts` file with the following content:

   ```ts
   // hardhat.config.ts
   import { defineConfig } from "hardhat/config";

   export default defineConfig({});
   ```

3. **Run the help command**

   Verify that Hardhat 3 is working by running the help command:

   <Run command="hardhat --help" />

## Progressively migrating your config

With a minimal version of Hardhat 3 working, you can migrate your config step by step.

Let's start with the minimal settings required to compile your contracts.

1. **Add a `solidity` entry**

   Copy the `solidity` entry from your old config as-is. The format is backwards-compatible in Hardhat 3, so it should just work:

   ```ts ins={5-7}
   // hardhat.config.ts
   import { defineConfig } from "hardhat/config";

   export default defineConfig({
     solidity: {
       /* your solidity config */
     },
   });
   ```

2. **Compile your contracts**

   Run the `build` task to verify that your config is working:

   <Run command="hardhat build" />

To learn more about the updated config format and continue with your migration, see [this section](/docs/reference/configuration#solidity-configuration).

## Migrating tests

This section assumes that your Hardhat 2 project uses Mocha as its test runner, which is the default.

1. **Install the recommended toolbox for Mocha and Ethers.js**

   Install the plugin:

   <Install packages="@nomicfoundation/hardhat-toolbox-mocha-ethers" />

   Then in your Hardhat config, import the plugin and add it to the list of plugins:

   ```ts ins={3,6}
   // hardhat.config.ts
   import { defineConfig } from "hardhat/config";
   import hardhatToolboxMochaEthers from "@nomicfoundation/hardhat-toolbox-mocha-ethers";

   export default defineConfig({
     plugins: [hardhatToolboxMochaEthers],
     solidity: {
       /* your solidity config */
     },
   });
   ```

   Unlike Hardhat 2, you need to both import the plugin and add it to the list of plugins.

2. **Update your test files**

   Updating tests is usually the most involved part of the migration, so we've created [a dedicated page](/docs/migrate-from-hardhat2/guides/mocha-tests) with the details.

   You can start by migrating a single test and run it individually to verify that it works as expected:

   <Run command="hardhat test test/some-test.ts" />

## Migrating custom tasks

In Hardhat 2, tasks were defined imperatively in the config file, and the action function was passed directly:

```ts
// Hardhat 2
task("accounts", "Prints the accounts", async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();
  for (const account of accounts) {
    console.log(account.address);
  }
});
```

In Hardhat 3, the equivalent uses `setInlineAction` and requires calling `.build()` and adding the task to the `tasks` array in your config:

```ts ins={4-5,8-9,13}
// hardhat.config.ts
import { defineConfig, task } from "hardhat/config";

const printAccounts = task("accounts", "Print the accounts")
  .setInlineAction(async (taskArguments, hre) => {
    const { provider } = await hre.network.create();
    console.log(await provider.request({ method: "eth_accounts" }));
  })
  .build();

export default defineConfig({
  // ... rest of the config
  tasks: [printAccounts],
});
```

For more complex tasks, you can use `setAction()` with a separate file for lazy loading. To learn more, see [Writing Hardhat tasks](/docs/guides/writing-tasks).

## Migrating `extendConfig` and `extendEnvironment`

These extensibility points were replaced by the hook system. We'll add details on how to migrate them soon.

## Migration blockers

If your migration is blocked by a missing feature or plugin, please let us know [in this issue](https://github.com/NomicFoundation/hardhat/issues/7207).
