Managing smart contract dependencies
Hardhat 3 supports dependencies installed with npm and via git submodules. This guide explains how to use each of them.
Using npm dependencies
Section titled “Using npm dependencies”To use an npm dependency in Hardhat you first need to install it. For example, you can install Open Zeppelin Contracts like this:
npm add --save-dev @openzeppelin/contractspnpm add --save-dev @openzeppelin/contractsyarn add --dev @openzeppelin/contractsTo use it, you have to import their files just like you would do in Node.js. For example, this file imports a file from @openzeppelin/contracts:
// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.20;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract ExampleToken is ERC20 { constructor() ERC20("ExampleToken", "ETK") {}}Hardhat treats files coming from npm differently than your local ones. They’re considered dependencies, not part of your project, so they don’t emit artifacts by default. To learn how to do it, read the npm artifacts recipe.
Why you should use npm dependencies
Section titled “Why you should use npm dependencies”Hardhat 3 offers full support for npm, including many new features. We recommend using them whenever possible, as they have multiple advantages:
-
They are lighter on your file system and faster to install when compared to git submodules.
-
They are more secure:
-
Once published to npm, dependencies are immutable, preventing authors from potentially attacking their users by replacing the code of a version.
-
They can have provenance certificates, so you can know precisely how a version was built and published.
-
They allow library authors to have stricter security practices (read more about npm’s security improvements).
-
You can replicate your setup exactly by keeping track of your lockfile using git.
-
-
They have native support for transitive dependencies, even with different versions.
Two dependencies can use incompatible versions of the same library and Hardhat will handle it automatically. New in Hardhat 3
-
They have native support for monorepos. New in Hardhat 3
-
They don’t require adding remappings after installation. Hardhat handles them automatically.
On top of that, library authors can customize which files they export and how using
package.json#exports. For example, making an import tolib/Foo.solresolve tolib/src/Foo.sol. New in Hardhat 3
Using git submodules
Section titled “Using git submodules”If you need to install a dependency using a git submodule, use this command:
git submodule add -b <branch> <repository> <installation-path>For example, this installs PaulRBerg/prb-math@release-v4 in the lib/prb-math folder of your project:
git submodule add -b release-v4 https://github.com/PaulRBerg/prb-math.git lib/prb-mathHardhat doesn’t treat files from git submodules differently, as it does with npm ones. They’re considered local to your project, but since they aren’t placed in your contracts/ folder, Hardhat doesn’t emit artifacts for them either.
To import them, you need to use a relative path, or use a remapping.