Hardhat vs Foundry: Complete Smart Contract Deployment Guide

When building a smart contract, choosing the right framework for development and deployment is as important as writing the code itself. Frameworks requiring manual handling of tasks like complex debugging lead to longer development cycles, impacting the efficiency, security, cost and maintainability of your dApp. Moreover, using one that isn’t widely adopted or lacks community support makes problem solving a hectic and time-consuming process.
Good frameworks integrate best practices and promote easy integration using ready-made libraries with audited and tested code for common functionalities, reducing the chance of introducing bugs or vulnerabilities.
This article will walk you through:
An Overview Of Smart Contracts
Hardhat Development Environment
Foundry Toolkit For Development
Setting Up Hardhat Runner
Compiling And Deploying Smart Contracts With Hardhat
Setting Up Foundry Toolkit
Compiling And Deploying Smart Contracts With Foundry
Smart Contract Verification
Comparison Of Hardhat And Foundry
When To Use Which
Understanding Smart Contracts
Smart contracts are self-executing programs stored on a blockchain that automates the actions required in a blockchain transaction. The development process involves writing the contract, compiling, testing and finally deploying it to the target blockchain network.
This article assumes familiarity with the following concepts and tools:
Core blockchain concepts
Wallets, Public and Private keys
Ethereum and the Ethereum Virtual Machine (EVM)
Smart Contracts
Basic Solidity syntax
RPC Endpoints (Alchemy, Infura or Quicknode)
Overview Of Hardhat Development Environment
The main component you will be interacting with in Hardhat is the Hardhat Runner which is designed around the concepts of tasks and plugins. Tasks are specific actions or commands that Hardhat executes and can be anything from compiling to running tests and deploying your contract. Plugins are features that extend Hardhat’s capabilities without having to modify the core code. This design keeps the features isolated, manageable and user-friendly.
Hardhat is built primarily with Javascript and Typescript ensuring seamless compatibility and easy integration with most Ethereum libraries which are written in Javascript. While Javascript provides flexibility, TypeScript adds static typing that helps developers catch mistakes before runtime.
In addition to the Runner, Hardhat’s environment includes other tools such as the Hardhat Network (which simulates a real Ethereum blockchain), Solidity Compiler Integration and Hardhat Ignition for deployment management.
Overview Of Foundry Toolkit For Development
Foundry is a Rust-based smart contract development toolkit which embodies a Solidity-first approach to building, testing and deploying dApps on the Ethereum blockchain and other EVM compatible networks.
It is essentially a suite of command-line tools that work together seamlessly. The primary tool, Forge, translates Solidity code into bytecode and ABIs during compilation. Anvil provides a quick and easy way to test contracts in a controlled local blockchain environment. It also allows you to fork live blockchains locally, enabling testing without deploying to mainnet.
Chisel is used to interactively test and experiment with Solidity code snippets directly in your terminal, providing immediate feedback that is useful for debugging or understanding specific solidity behaviours. Cast allows you to send tokens, execute contract functions from your terminal, query blockchain data, and create scripts for various interactions with Ethereum and other EVM compatible blockchains.
Setting Up Hardhat Runner
Before getting started, ensure you have the following requirements:
1. Node.js: Download and install Node.js version 18 or higher from nodejs.org
2. An Etherscan API Key Follow these steps to get your API key:
- Visit etherscan.io and sign up for a free account
Navigate to https://etherscan.io/apidashboard
Click the "Add" button to create a new API key
- Copy the generated API key, you’ll need it soon
Step 1: Create a Project Directory and Initialize Node.js
First, create a new directory for your Hardhat project and navigate into it:
mkdir my-hardhat-project
cd my-hardhat-project
Initialize a new Node.js project:
npm init -y
This creates a package.json file with default settings for your project.
Step 2: Install Hardhat
Install Hardhat as a development dependency:
npm install --save-dev hardhat
This command downloads the Hardhat package, saves it in your node_modules folder, and adds it to the devDependencies section in your package.json file.
Step 3: Initialize a Hardhat Project
Run the Hardhat initialization wizard using npx (Node Package eXecutor), which allows you to execute packages from your local node_modules:
npx hardhat init
You'll be presented with several project template options:
For this tutorial, select "Create a TypeScript project" (or "Create a JavaScript project" if you prefer) and follow the prompts. This will generate the basic project structure with sample contracts and configuration files.
Step 4: Explore Hardhat's Built-in Tasks
View all available Hardhat tasks by running:
npx hardhat
This displays a comprehensive list of available tasks, their descriptions, and global options. You'll see tasks for compiling, testing, deploying, and more.
Step 5: Set Up Environment Variables
Create a .env file in your project root to store sensitive information:
touch .env
Add the following variables to your .env file:
# .env
PRIVATE_KEY=your_wallet_private_key_here
RPC_URL=rpc_url_of_your_selected_chain
ETHERSCAN_KEY=your_etherscan_api_key_here
Step 6: Configure Hardhat
Open your hardhat.config.ts file and configure it for deployment. Here’s a sample using Sepolia
const { PRIVATE_KEY, ETHERSCAN_KEY, RPC_URL} = process.env; //Create a .env file in your root folder containing these variables
const config: HardhatUserConfig = {
solidity: {
version: "0.8.28",
},
networks: {
hardhat: {
chainId: 1337,
},
Sepolia: {
url: RPC_URL,
accounts: [`0x${PRIVATE_KEY}`],
chainId: 11155111,
},
},
etherscan: {
apiKey: ETHERSCAN_KEY,
},
};
export default config;
Compiling and Deploying Smart Contracts With Hardhat
Before proceeding, ensure your hardhat.config.ts file is properly configured as shown in the previous step:
Step 1: Compile Your Smart Contracts
Navigate to your project's root directory in the terminal and run the compile task:
npx hardhat compile
Step 2: Deploy to Your Target Network
Run your deployment script, specifying the target network:
npx hardhat run scripts/deploy.js --network <network_name>
For example, to deploy to Sepolia testnet:
npx hardhat run scripts/deploy.js --network sepolia
The address your contract was deployed to should come up in your terminal. You have successfully deployed a contract on hardhat.
Setting Up Foundry ToolKit
Step 1: Install Foundry
Foundry provides a convenient installation script. Open your terminal and run:
curl -L https://foundry.paradigm.xyz | bash
After the script finishes, install Foundry's dependencies and tools using the foundryup command:
foundryup
Step 2: Verify Installation
In a new terminal, confirm that all Foundry tools are correctly installed and accessible:
forge --version
anvil --version
cast --version
chisel --version
Step 3: Create a New Foundry Project
Initialize a new Foundry project with the built-in template:
forge init my-foundry-project
cd my-foundry-project
This command creates a new directory with
src/ - Your smart contract source files
test/ - Test files written in Solidity
script/ - Deployment and interaction scripts
foundry.toml - Configuration file
Sample contract and test files to get you started
Compiling and Deploying Smart Contracts With Foundry
Ensure you have Foundry installed and a new project created from the previous steps.
Step 1: Set Up Environment Variables
Create a .env file in your project root to store sensitive information:
touch .env
Add the following variables to your .env file:
# .env
PRIVATE_KEY=your_wallet_private_key_here
RPC_URL=rpc_url_of_your_selected_chain
ETHERSCAN_KEY=your_etherscan_api_key_here
Ensure you never commit the .env file when pushing to GitHub, ensure it is listed in .gitignore.
source .env
Step 2: Compile Your Smart Contracts
forge build
This step is optional as the contract would automatically compile when you run the deployment command in the next step. But it is recommended to compile first.
Step 4: Deploy Your Smart Contract
Then deploy to the local network using this command
forge create --rpc-url $RPC_URL --private-key $PRIVATE_KEY src/Counter.sol:Counter --broadcast
Smart Contract Verification
Transparency and trust are the core ethos of blockchain technology. Because the blockchain is immutable, once a contract is deployed, its code cannot be changed without deploying a new contract. This makes verification crucial as it ensures that the code you see is actually the code that's running and hasn't been tampered with after deployment.
Smart contract verification confirms that a contract’s source code matches its deployed bytecode on the blockchain. This is also essential for debugging issues, analysing transaction behaviour, auditing vulnerabilities and optimizing contract performance.
Verification using Hardhat or Foundry is a straightforward process:
1. Using Hardhat: After deploying your contract with Hardhat, run the verification command:
npx hardhat verify --network <network-name> <contract-address>
Upon successful verification, the terminal will display a confirmation message with the verification URL.
2. Using Foundry: After deployment, use the forge verify-contract command:
forge verify-contract <contract-address> <contract-name> --watch --chain-id <chain-id>
The terminal will show the verification progress and success confirmation.
Comparison of Hardhat and Foundry
Hardhat offers a more mature, established and extensive plugin ecosystem. There’s a plugin for virtually any need, be it wallet integration, etherscan verification, gas reporting, TypeScript generation or third party services. It has been designed from the ground up to be highly extensible and flexible, providing a low barrier to entry and a gentler learning curve. This explains its deep integration in the web ecosystem and familiarity with most transitioning web developers.
Regarding performance, Foundry has clear advantages as its architecture aims for blazing fast execution and streamlined workflows. While hardhat requires external tools for advanced testing, Foundry incorporates fuzz testing with Forge.
Hardhat Network and Anvil function similarly as in-process local EVM networks. Hardhat Network provides easy mainnet forking while Anvil offers functions that allow direct manipulation of EVM state and detailed transactions call traces. Anvil also supports mainnet forking, enabling realistic testing similar to Hardhat Network.
Feature / Metric | Hardhat (JavaScript/TypeScript) | Foundry (Rust/Solidity) |
Core Features | JavaScript/TypeScript language and testing, Solidity compiler integration, built-in debugger, third-party plugins for fuzz testing, limited invariant testing, plugin required for Vyper with a local EVM instance | Rust language, Solidity native testing, auto-detects Solidity versions, interactive debugger + console.sol, built-in advanced fuzzing, native invariant testing, built-in Vyper support |
Performance Metrics | JavaScript/TypeScript runtime, Node.js single-threaded build, higher memory usage (Node.js overhead), larger installation size (npm dependencies) | Ultra-fast Rust-based execution, parallelized multi-core compilation, lower memory usage and smaller installation size |
Development Experience | Moderate setup complexity, multiple config files, enhanced Git submodules support in v3, excellent VS Code integration, familiar to JS developers. | Simple setup (curl install), native remapping support, full submodule support, good IDE integration, steeper learning curve for non-Rust devs. |
Testing Capabilities | External libraries for fuzz testing, limited property testing, moderate test speed, plugin-based gas reporting, third-party coverage tools. | Advanced built-in fuzzing, comprehensive invariant testing, extremely fast test execution, built-in gas reporting, native coverage tools. |
Tooling Ecosystem | Hardhat Network, Hardhat console, limited REPL, hardhat-verify plugin, script-based deployment. | Anvil (faster forking), Cast (Swiss Army knife), Chisel (Solidity REPL), built-in verification, Forge scripts |
Platform & Migration | Cross-platform (Node.js), extensive npm plugin ecosystem, simplified migration from Hardhat 2, compatible with v2 scripts, easy npm migration. | Cross-platform (native binaries), modular built-in tools, requires project rewrite, supports Hardhat repo structures, manual dependency handling. |
When To Choose Which
The choice between these frameworks comes down to their alignment with your project’s specific requirements and your development priorities.
If you are building a full-stack dApp that requires extensive integration with web frontends and off-chain services, Hardhat is better suited because it provides a highly flexible environment with plugins for specific needs. However, in exchange for language familiarity, you’ll need to be comfortable with a slightly slower feedback loop for testing.
If you prioritize speed and performance in compilation and testing, need advanced testing capabilities, want powerful EVM manipulation for precise testing scenarios or you are an auditor or developer focused purely on smart contract logic, Foundry is your go-to choice. You’ll need to be comfortable with a steeper initial learning curve if you’re not familiar with its Solidity-native approach.
Many teams leverage both strategically, using Foundry’s speed for rapid development and testing while tapping into Hardhat's ecosystem for deployment and integration tasks. Either way, making an informed framework choice from the start will save you significant time and complexity down the road.
References
https://hardhat.org/hardhat-runner/docs/getting-started#overview
https://medium.com/coinmonks/hardhat-for-solidity-development-b11e9f174f3a
https://metamask.io/news/hardhat-vs-foundry-choosing-the-right-ethereum-development-tool
https://docs.hedera.com/hedera/core-concepts/smart-contracts/verifying-smart-contracts-beta
https://medium.com/buildbear/a-comprehensive-guide-to-smart-contract-verification-3755afe54d6b
https://dev.to/abhinavxt/introduction-to-smart-contract-development-using-foundry-502l
Subscribe to my newsletter
Read articles from Valerie Nwajei directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
