Hardhat plugin that adds Hardhat support to Foundry projects for seamless Ethereum development workflow integration
npx @tessl/cli install tessl/npm-nomicfoundation--hardhat-foundry@1.2.00
# Hardhat Foundry
1
2
The `@nomicfoundation/hardhat-foundry` plugin enables seamless integration between Hardhat and Foundry development environments for Ethereum smart contract projects. It automatically configures Hardhat to use Foundry's contracts directory structure and dependency management system, allowing developers to leverage both tools' strengths within a single project.
3
4
## Package Information
5
6
- **Package Name**: @nomicfoundation/hardhat-foundry
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @nomicfoundation/hardhat-foundry`
10
11
## Core Imports
12
13
```typescript
14
import "@nomicfoundation/hardhat-foundry";
15
```
16
17
For accessing utility functions:
18
19
```typescript
20
import {
21
getForgeConfig,
22
parseRemappings,
23
getRemappings,
24
installDependency,
25
HardhatFoundryError
26
} from "@nomicfoundation/hardhat-foundry/dist/src/foundry";
27
```
28
29
## Basic Usage
30
31
The plugin works automatically once imported in your Hardhat configuration:
32
33
```typescript
34
// hardhat.config.ts
35
import "@nomicfoundation/hardhat-foundry";
36
37
export default {
38
solidity: "0.8.19",
39
// Other Hardhat config...
40
};
41
```
42
43
For projects without Foundry setup, initialize it:
44
45
```bash
46
npx hardhat init-foundry
47
```
48
49
## Architecture
50
51
The plugin consists of several key components:
52
53
- **Configuration Extension**: Automatically modifies Hardhat configuration when `foundry.toml` is present
54
- **Path Management**: Configures source and cache paths based on Foundry configuration
55
- **Remapping Integration**: Adds Foundry remapping support to Hardhat compilation system
56
- **Task System**: Provides `init-foundry` task for project setup
57
- **Utility Functions**: Core functions for interacting with Foundry toolchain
58
59
## Capabilities
60
61
### Plugin Configuration
62
63
The plugin automatically extends Hardhat configuration to integrate with Foundry projects when a `foundry.toml` file is present.
64
65
**Configuration Extension (Automatic)**
66
67
When imported, the plugin automatically:
68
- Checks for `foundry.toml` presence and warns if missing
69
- Loads Foundry configuration using `forge config --json`
70
- Updates Hardhat's sources path to match Foundry's `src` configuration
71
- Modifies cache path to prevent conflicts with Foundry's cache
72
- Validates user-configured paths against Foundry configuration
73
74
### Project Initialization
75
76
Initialize Foundry setup in existing Hardhat projects.
77
78
```typescript { .api }
79
/**
80
* Hardhat task that initializes Foundry setup in current project
81
* Creates foundry.toml file and installs forge-std dependency
82
* Usage: npx hardhat init-foundry
83
* @task init-foundry
84
*/
85
```
86
87
The `init-foundry` task:
88
- Creates a `foundry.toml` file with appropriate configuration
89
- Sets up proper source, output, and library paths
90
- Installs `foundry-rs/forge-std` dependency automatically
91
- Configures cache paths to avoid conflicts
92
93
**Generated foundry.toml structure:**
94
```toml
95
[profile.default]
96
src = 'contracts'
97
out = 'out'
98
libs = ['node_modules', 'lib']
99
test = 'test'
100
cache_path = 'cache_forge'
101
```
102
103
### Foundry Configuration Access
104
105
Retrieve Foundry project configuration data.
106
107
```typescript { .api }
108
/**
109
* Gets the current Foundry configuration by running `forge config --json`
110
* @returns Foundry configuration object containing src, cache_path, and other config properties
111
*/
112
function getForgeConfig(): {
113
src: string;
114
cache_path: string;
115
out: string;
116
libs: string[];
117
test: string;
118
remappings: string[];
119
[key: string]: any;
120
};
121
```
122
123
**Usage Example:**
124
125
```typescript
126
import { getForgeConfig } from "@nomicfoundation/hardhat-foundry/dist/src/foundry";
127
128
const config = getForgeConfig();
129
console.log(config.src); // e.g., "contracts"
130
console.log(config.cache_path); // e.g., "cache_forge"
131
```
132
133
### Remapping Management
134
135
Parse and retrieve Foundry remappings for dependency resolution.
136
137
```typescript { .api }
138
/**
139
* Parses Foundry remappings from text format into a mapping object
140
* @param remappingsTxt - Raw remappings text from `forge remappings`
141
* @returns Object mapping remapping prefixes to their target paths
142
*/
143
function parseRemappings(remappingsTxt: string): Record<string, string>;
144
145
/**
146
* Gets Foundry remappings by running `forge remappings` (cached)
147
* @returns Promise resolving to remappings object
148
*/
149
function getRemappings(): Promise<Record<string, string>>;
150
```
151
152
**Usage Examples:**
153
154
```typescript
155
import { parseRemappings, getRemappings } from "@nomicfoundation/hardhat-foundry/dist/src/foundry";
156
157
// Parse remappings manually
158
const remappings = parseRemappings("@openzeppelin/=lib/openzeppelin-contracts/\n@forge-std/=lib/forge-std/src/");
159
console.log(remappings);
160
// { "@openzeppelin/": "lib/openzeppelin-contracts/", "@forge-std/": "lib/forge-std/src/" }
161
162
// Get remappings automatically (cached)
163
const currentRemappings = await getRemappings();
164
console.log(currentRemappings);
165
```
166
167
**Remapping Format Rules:**
168
- Each line contains one remapping in format `prefix=target`
169
- Context remappings (containing `:`) are not allowed
170
- Remappings without targets (no `=`) are not allowed
171
- First occurrence wins if duplicate prefixes exist
172
- Empty lines are ignored
173
174
### Dependency Installation
175
176
Install Foundry dependencies using forge install.
177
178
```typescript { .api }
179
/**
180
* Installs a Foundry dependency using `forge install`
181
* @param dependency - Dependency identifier (e.g., "foundry-rs/forge-std")
182
* @returns Promise that resolves when installation completes
183
*/
184
function installDependency(dependency: string): Promise<void>;
185
```
186
187
**Usage Example:**
188
189
```typescript
190
import { installDependency } from "@nomicfoundation/hardhat-foundry/dist/src/foundry";
191
192
// Install forge standard library
193
await installDependency("foundry-rs/forge-std");
194
195
// Install OpenZeppelin contracts
196
await installDependency("OpenZeppelin/openzeppelin-contracts");
197
```
198
199
The function automatically:
200
- Checks if `--no-commit` flag is supported
201
- Uses the appropriate forge install command with or without the flag
202
- Provides colored console output for the command being run
203
- Throws `ForgeInstallError` if installation fails
204
205
### Error Handling
206
207
Comprehensive error handling for Foundry-related operations.
208
209
```typescript { .api }
210
/**
211
* Main error class for hardhat-foundry plugin operations
212
*/
213
class HardhatFoundryError extends NomicLabsHardhatPluginError {
214
constructor(message: string, parent?: Error);
215
}
216
217
/**
218
* Specialized error class for forge install command failures
219
*/
220
class ForgeInstallError extends HardhatFoundryError {
221
constructor(dependency: string, parent: Error);
222
}
223
```
224
225
**Common Error Scenarios:**
226
227
1. **Missing Foundry Installation**: When `forge` command is not available (exit code 127)
228
2. **Invalid Configuration**: When `foundry.toml` file has syntax errors (exit code 134)
229
3. **Path Mismatch**: When user-configured sources path doesn't match Foundry configuration
230
4. **Missing Configuration Keys**: When required `src` or `cache_path` keys are missing
231
5. **Invalid Remappings**: When remappings contain contexts or lack targets
232
6. **Installation Failures**: When `forge install` fails for dependencies (throws `ForgeInstallError`)
233
234
**Usage Example:**
235
236
```typescript
237
import { HardhatFoundryError, getForgeConfig } from "@nomicfoundation/hardhat-foundry/dist/src/foundry";
238
239
try {
240
const config = getForgeConfig();
241
} catch (error) {
242
if (error instanceof HardhatFoundryError) {
243
console.error("Foundry integration error:", error.message);
244
}
245
}
246
```
247
248
## Internal Task Integration
249
250
The plugin integrates with Hardhat's internal compilation system through task overrides:
251
252
**Remapping Integration**: The plugin overrides `TASK_COMPILE_GET_REMAPPINGS` to provide Foundry remappings during compilation.
253
254
**Version Compatibility**: The plugin overrides `TASK_COMPILE_TRANSFORM_IMPORT_NAME` to ensure compatibility with Hardhat >= 2.17.2.
255
256
These integrations are automatic and don't require direct interaction from users.
257
258
## Types
259
260
```typescript { .api }
261
// Internal type for remapping storage
262
type Remappings = Record<string, string>;
263
264
// Error classes
265
class HardhatFoundryError extends NomicLabsHardhatPluginError {
266
constructor(message: string, parent?: Error);
267
}
268
269
// Specialized error class for forge install command failures
270
class ForgeInstallError extends HardhatFoundryError {
271
constructor(dependency: string, parent: Error);
272
}
273
```
274
275
## Dependencies
276
277
**Runtime Dependencies:**
278
- `picocolors`: ^1.1.0 - For colored console output
279
280
**Peer Dependencies:**
281
- `hardhat`: ^2.26.0 - Required Hardhat framework
282
283
**Node.js Built-ins:**
284
- `fs`: File system operations
285
- `path`: Path manipulation
286
- `child_process`: Command execution
287
- `util`: Utility functions