Library / SDK
PaulRBerg/foundry-template avatar
PaulRBerg/foundry-template

foundry-template gives a Solidity project Bun, OpenZeppelin and linting by default

Foundry-based template for developing Solidity smart contracts

642 stars134 forksSolidityMIT

At a glance

What is it?
PaulRBerg's foundry-template is a starting point for Solidity work on Foundry, with dependencies managed as Node.js packages through Bun instead of git submodules, OpenZeppelin pre-installed, and Prettier, Solhint and Forge formatting wired into one command. It saves setup time and settles several arguments, at the cost of one more package manager in the loop.
Who is it for?
foundry-template suits a Solidity developer starting a new repository who wants Forge, Forge Std, OpenZeppelin, Prettier and Solhint already configured and a single command that checks formatting and linting. It is the wrong tool if your team standardises on git submodules for Solidity dependencies, because Bun is the mechanism here, and it is the wrong tool if you want a project with a deployment pipeline or a published package, since this is a template and not a framework.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 14 days ago.
What is it written in?
Mainly Solidity, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Bun instead of submodules, and that is the whole idea

The template's stated purpose is a Foundry based template for developing Solidity smart contracts with sensible defaults, and the sentence that distinguishes it from every other starter is about dependencies. They are managed as Node.js packages via Bun rather than git submodules, and the template ships preconfigured with Forge Std, OpenZeppelin Contracts, Prettier and Solhint. The choice of Bun is not incidental decoration. Git submodules for Solidity libraries have a well known set of annoyances, a pinned commit per dependency, an extra clone step, and a working tree that is easy to leave in a strange state. Treating the same libraries as package dependencies moves them into a lockfile and an install command, and Bun is the tool that does that here. The repository listing confirms the shape of the result. There is a bun.lock at the root, a package.json, a foundry.toml, a remappings.txt, a src/ directory for the contracts, a tests/ directory, a script/ directory, and a .serena/ directory alongside .agents/, .claude/ and .devcontainer/. There is a .gitpod.yml for Gitpod, a .vscode/ directory, an .env.example, a .solhint.json for the linter configuration and a .prettierrc.yml with a .prettierignore. The project is MIT licensed, and the README links the Foundry Book and the writing tests page for the details the template does not cover.

What is inside, and what each piece is for

The What's Inside list is short because the parts are well known, and the value is in which ones are pre-wired. Forge is the toolchain entry point, used to compile, test, fuzz, format and deploy smart contracts, so one binary covers the whole loop from editing to deployment. Forge Std is the collection of helpful contracts and utilities for testing, and it is pinned in the package metadata to a specific tag, github:foundry-rs/forge-std#v1.16.2, which is the usual way to reference a git dependency when the package manager is the one doing the resolution. OpenZeppelin Contracts is the library of secure, community-vetted smart contracts and it is pre-installed, pinned at 5.7.0 as a regular dependency rather than a git reference, which is the clearest illustration of the Bun approach. Prettier is the code formatter for non-Solidity files and Solhint is the linter for Solidity code, so the pair covers both halves of a Solidity repository. The template also links four related projects, the upstream forge-template, refcell's template, cleanunicorn's ethereum-smartcontract-template and FrankieIsLost's forge-template, which is a reasonable set of alternatives to look at if this one's defaults do not suit you.

The scripts section is the real documentation

The package.json is where the template's opinions become commands, and the scripts object is short enough to read in one glance. There is a clean script that removes the cache and out directories, a build script that runs forge build, and a test script that runs forge test.

json
  "scripts": {
    "clean": "rm -rf cache out",
    "build": "forge build",
    "forge-check": "forge fmt --check",
    "forge-write": "forge fmt",
    "full-check": "bun run forge-check && bun run solhint-check && bun run prettier:check",
    "full-write": "bun run forge-write && bun run prettier:write",
    "prettier:check": "prettier --check \"**/*.{json,md,yml}\"",
    "prettier:write": "prettier --write \"**/*.{json,md,yml}\"",
    "solhint-check": "bun solhint \"{script,src,tests}/**/*.sol\"",
    "test": "forge test"
  }

Three things stand out. The naming is split into a check form and a write form for every tool, which is the convention that makes a CI job easy: full-check fails when something is unformatted or the lint fails, and full-write fixes what it can. The Prettier glob covers json, md and yml, so the formatter handles the non-Solidity half of the repository while Solhint covers the Solidity half, and Solhint's glob spans script, src and tests. And every script is invoked through bun run, so the package manager is the entry point for the whole workflow rather than a separate tool you have to remember to install.

Environment variables, and what a template can and cannot decide for you

The .env.example file is the honest list of what a Solidity project needs from the outside world, and it is short. It exports an Alchemy API key, an Etherscan API key, a Routemesh API key, a mnemonic, and a Foundry profile named default.

bash
export API_KEY_ALCHEMY="YOUR_API_KEY_ALCHEMY"
export API_KEY_ETHERSCAN="YOUR_API_KEY_ETHERSCAN"
export ROUTEMESH_API_KEY="YOUR_ROUTEMESH_API_KEY"
export MNEMONIC="YOUR_MNEMONIC"
export FOUNDRY_PROFILE="default"

The pattern is instructive about what the template does not decide. The Alchemy key and the Etherscan key are for the two services a Solidity developer touches most, one for node access and one for contract verification, and the Routemesh key is for a router interface, which matters if your contracts call a router. The mnemonic is the one entry that deserves a second look, since it is a signing seed and a template that ships a mnemonic placeholder is inviting you to leave the placeholder in place. The Foundry profile is the mechanism for switching between networks and fork configurations, and the example sets it to default. The deeper point is that a template can standardise the toolchain, the dependency resolution and the checks, but it cannot standardise your key management, and a value like a mnemonic is the one a developer is most likely to leave as it found.

Generating a project and the CI setup that comes with it

There is no command in the README for creating a project from the template, because the mechanism is GitHub's own. The Use this template link points at the repository's generate page, and the README carries a Gitpod badge alongside a GitHub Actions badge, which tells you two things about the intended workflow. The first is that a new repository starts from this one in a click, and the second is that there is an automated build wired in from the start. The GitHub Actions workflow lives in .github/, and the badge points at a ci.yml workflow, so the checks that full-check performs are the checks that CI runs. The presence of a .devcontainer/ directory, a .gitpod.yml, a .vscode/ directory and a .serena/ directory shows a project that expects to be opened in several editor and cloud environments, which is normal for a Solidity repository where people work in different places. The AGENTS.md file is worth reading first, and the README is explicit about why. Contributions are welcome and AGENTS.md is where the development workflow, commands and conventions live, which is the file that tells a new contributor how the maintainer wants the tooling to be run.

How this differs from the other Solidity starters

The four related projects the README links make the comparison concrete, because they differ on exactly the axis this template cares about. The upstream forge-template is the reference point, and it handles dependencies as git submodules, so adopting it means your team learns the submodule workflow. refcell's template goes further in the same direction and treats dependencies as a first class package problem, which is the same idea as this one expressed with a different tool. cleanunicorn's ethereum-smartcontract-template and FrankieIsLost's forge-template take different positions on which pieces to include, with the usual variation in whether a frontend, a deploy script or a test fixture set is bundled. What the Bun approach buys is that the dependency list in package.json is the dependency list, there is one lockfile, and the same install command works for a new contributor as for CI. What it costs is a second toolchain in the project. If your organisation has already standardised on npm and the Solidity dependencies come from a registry, the picture changes, and if your organisation has standardised on submodules, this template will fight that. The decision is not about Solidity at all, it is about which package manager your team is willing to run.

Editorial conclusion

foundry-template suits a Solidity developer starting a new repository who wants Forge, Forge Std, OpenZeppelin, Prettier and Solhint already configured and a single command that checks formatting and linting. It is the wrong tool if your team standardises on git submodules for Solidity dependencies, because Bun is the mechanism here, and it is the wrong tool if you want a project with a deployment pipeline or a published package, since this is a template and not a framework. Before you adopt it, read AGENTS.md, which the README points to for the development workflow, commands and conventions, and decide whether adding Bun to the toolchain is acceptable to everyone who will clone the repository.

Frequently asked questions

How does foundry-template manage Solidity dependencies?

As Node.js packages via Bun rather than git submodules, with OpenZeppelin Contracts pre-installed as a dependency at version 5.7.0 and forge-std referenced as a git dependency pinned to the v1.16.2 tag. The repository carries a bun.lock at the root.

What does the full-check script in foundry-template run?

It chains three checks: forge fmt --check for Solidity formatting, solhint over the script, src and tests directories for linting, and prettier --check over json, md and yml files. The companion full-write script runs forge fmt and prettier --write to fix what it can.

Which environment variables does the foundry-template expect?

The .env.example file exports API_KEY_ALCHEMY, API_KEY_ETHERSCAN, ROUTEMESH_API_KEY, MNEMONIC and FOUNDRY_PROFILE, with the profile defaulting to default. The Alchemy and Etherscan keys cover node access and contract verification, and the mnemonic is the signing seed for local deployments.

Official sources

  1. Issues
  2. License: MIT
  3. PaulRBerg/foundry-template on GitHub
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/paulrberg-foundry-template.svg)](https://hysenlabs.com/projects/paulrberg-foundry-template)

Was this useful?