How to easily import dependencies and use remappings in Foundry

Samarth SaxenaSamarth Saxena
3 min read

Introduction

In this series of blogs, we’ve so far seen how we can install Foundry and write and compile simple contracts in it. If you have dependencies like ERC20 by OpenZeppelin in your contract, the process of importing and using them is slightly different from what you might be used to. In this short guide, let’s see how we’re supposed to go about it.

Importing dependencies

We will not be getting our dependencies from npm. So, instead of writing npm install dependency like in Hardhat, you’ll be using forge install dependency and here, dependency can be a raw URL (https://foo.com/dep), an SSH URL (git@github.com:owner/repo), or the path to a GitHub repository (owner/repo). If you still have the Foundry project we made in the last blog, point your terminal to it. For this guide, let’s suppose we want to use OpenZeppelin’s ERC20 contract. To do that, run

forge install openzeppelin/openzeppelin-contracts

This clones OpenZeppelin’s openzeppelin-contracts repository and installs it as a git submodule.

Now, create a new contract called Token.sol inside src and past the following code inside it

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract NewToken is ERC20 {
    constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {
        _mint(msg.sender, 10 * 10 ** 18);
    }
}

At this point, your IDE may be giving you many errors saying that it cannot find OpenZeppelin contracts, but running forge compile works without errors. What’s going on?

Forge remappings

When you run forge install, Foundry adds your dependencies to the lib folder. If you click on it right now, you will see 2 folders: forge-std and openzeppelin-contracts. The contract we want to use is stored in lib/openzeppelin-contracts/contracts/….ERC721Enumerable.sol so we can either import it using this path or we can remap lib/openzeppelin-contracts/contracts/ to @openzeppelin/contracts/ so that we can use the format we’re so used to. Well here’s the good part: Foundry does this for us automatically! To see all the remappings inferred by Foundry, run

forge remappings

Now to get rid of the errors that we see in our IDEs, we just need to create a file with all the remappings inside. We can do this easily by using:

forge remappings > remappings.txt

This will create a file called remappings.txt which will have all the remappings. It should look like this:

@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/
ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/
erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/
forge-std/=lib/forge-std/src/
openzeppelin-contracts/=lib/openzeppelin-contracts/

The path on the left hand side of the = sign is equivalent to the path on its right hand side in each line.

Conclusion

That’s it! You’ve successfully installed, imported and remapped dependencies in your Foundry project. Great work! As we inch closer to actually deploying a contract it is important to understand how private your private key is supposed to be. So, in the next blog, we’ll be discussing how you can safely store and use your private key for deploying contracts. See you then 🫡🫡

0
Subscribe to my newsletter

Read articles from Samarth Saxena directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Samarth Saxena
Samarth Saxena

I am a Web3 Developer and Technical Writer from India. I love to write about the things I learn and understand. I believe that being serious is not required as long as one is sincere. I thus tend to have fun in everything that I do.