# Overview
Hardhat Ignition is a declarative system for deploying smart contracts on Ethereum. It enables you to define smart contract instances you want to deploy, and any operation you want to run on them. By taking over the deployment and execution, Hardhat Ignition lets you focus on your project instead of getting caught up in the deployment details.
In Hardhat Ignition, deployments are defined through Ignition Modules. These modules serve as abstractions, helping you outline and describe the system that you want to deploy. Each Ignition Module encapsulates a group of smart contract instances and operations within your system.
You can think of Ignition Modules as being conceptually similar to JavaScript modules. In JavaScript, you create a module to group definitions of functions, classes, and values, and then you export some of them. In Hardhat Ignition, you create a module where you group definitions of smart contract instances and operations, and you export some of those contracts.
Creating a module doesn't lead to an interaction with the Ethereum network. After your modules are defined, then you can ask Hardhat Ignition to deploy them.
This declarative approach provides Hardhat Ignition with the autonomy to determine the best way to execute your deployment. It leverages this advantage to execute steps in parallel, manage and recover from errors, resume interrupted or partial deployments, and even adapt to modifications in your modules.
This guide will walk you through the steps to install Hardhat Ignition into an existing Hardhat project, define your first module, and deploy it.
TIP
If you don't have a Hardhat project yet, or if you want to create a new one to try Hardhat Ignition, please follow this guide first.
# Installation
To install Hardhat Ignition in an existing Hardhat project, you will need:
- Hardhat version 2.18.0 or higher
- Ethers.js version 6 or higher
You can also follow Hardhat's Quick Start guide to create a new project from scratch to follow this guide.
TIP
If you prefer to use Viem instead of ethers, check out the Viem guide for installation instructions.
Once you have a Hardhat project ready, open a terminal in its root directory, and run:
npm install --save-dev @nomicfoundation/hardhat-ignition-ethers
npm install --save-dev @nomicfoundation/hardhat-ignition-ethers @nomicfoundation/hardhat-ethers @nomicfoundation/hardhat-ignition @nomicfoundation/hardhat-verify @nomicfoundation/ignition-core ethers
yarn add --dev @nomicfoundation/hardhat-ignition-ethers @nomicfoundation/hardhat-ethers @nomicfoundation/hardhat-ignition @nomicfoundation/hardhat-verify @nomicfoundation/ignition-core ethers
pnpm add -D @nomicfoundation/hardhat-ignition-ethers @nomicfoundation/hardhat-ignition ethers
Finally, add this to your config file to enable the plugin:
import "@nomicfoundation/hardhat-ignition-ethers";
require("@nomicfoundation/hardhat-ignition-ethers");
# Quick start
We are going to explore a basic scenario where we deploy a simple contract and then run a post-deployment initialization function.
#Creating your contract
Paste the following code into contracts/Rocket.sol
:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
contract Rocket {
string public name;
string public status;
constructor(string memory _name) {
name = _name;
status = "ignition";
}
function launch() public {
status = "lift-off";
}
}
It contains a simple smart contract called Rocket
, featuring a launch
function that we'll call after deployment.
#Creating your first module
Modules are defined in JavaScript or TypeScript files inside of ignition/modules
. Let's create that folder structure:
mkdir ignition
mkdir ignition/modules
And paste the following code into a ignition/modules/Apollo.ts
. We'll explain it in a moment.
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
export default buildModule("Apollo", (m) => {
const apollo = m.contract("Rocket", ["Saturn V"]);
m.call(apollo, "launch", []);
return { apollo };
});
And paste the following code into a ignition/modules/Apollo.js
. We'll explain it in a moment.
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");
module.exports = buildModule("Apollo", (m) => {
const apollo = m.contract("Rocket", ["Saturn V"]);
m.call(apollo, "launch", []);
return { apollo };
});
The first aspect to note is that modules are created by calling the buildModule
function, which requires a module ID and a callback function. Our module will be identified as "Apollo"
.
The callback function is where the module definition actually happens. The m
parameter being passed into the callback is an instance of a ModuleBuilder
, which is an object with methods to define and configure your smart contract instances.
When we call these ModuleBuilder
methods, they create a Future
object, which represents the result of an execution step that Hardhat Ignition needs to run to deploy a contract instance or interact with an existing one.
This doesn't execute anything against the network, it simply represents it internally. After the Future
is created, it gets registered within the module, and the method returns it.
In our module, we created two Future
objects by calling the contract
and call
methods. The initial one instructs Hardhat Ignition to deploy a Rocket
contract instance, specifying "Saturn V"
as the only constructor parameter. The second one indicates that we intend to execute the launch
function of the deployed Rocket
instance, with no arguments provided.
Finally, we return the Future
object representing the Rocket
contract instance, to make it accessible to other modules and tests as well.
#Deploying it
Now that our module definition is ready, let's deploy it to a local Hardhat node. Let's start by spinning up a local node:
npx hardhat node
Next, in a terminal in the root of your Hardhat project, run:
npx hardhat ignition deploy ignition/modules/Apollo.ts --network localhost
npx hardhat ignition deploy ignition/modules/Apollo.js --network localhost
Hardhat Ignition will execute every Future
that we defined in the right order, and display the results:
Hardhat Ignition 🚀
Deploying [ Apollo ]
Batch #1
Executed Apollo#Rocket
Batch #2
Executed Apollo#Rocket.launch
[ Apollo ] successfully deployed 🚀
Deployed Addresses
Apollo#Rocket - 0x5fbdb2315678afecb367f032d93f642f64180aa3
A ignition/deployments/chain-31337
folder will be created. This contains all details about your deployment. Hardhat Ignition uses this data to recover from errors, resume a modified deployment, and more.
That's all it takes to define and execute a deployment using Hardhat Ignition. Check out the rest of the guides to learn more!