Recently, I noticed that 1inch was moving projects to Hardhat 3 for a reason I did not expect: it was faster for their workflow.
Even more interesting, the Hardhat team is working closely with them on a build shaped around the way 1inch actually develops and tests contracts. The public announcement is careful with the details. It says 1inch has been providing feedback while migrating its projects, but the direction is clear. This is not the old Hardhat waiting for plugins to fill the gaps. The team is working directly with major protocol developers and optimizing around real production workloads.
Before getting into what changed, a quick recommendation: if you want to learn Ethereum development by actually building, try Speedrun Ethereum. As part of my DevRel work with the Ethereum Foundation, I spend a lot of time thinking about how developers get from understanding Solidity to shipping real applications. Speedrun Ethereum is one of the best ways to make that jump: a sequence of hands-on challenges covering tokenization, crowdfunding, DEXs, oracles, lending, stablecoins, prediction markets, and more. It also happens to use Hardhat in its introductory challenge, which makes it a useful way to experience the workflow this article is about rather than only reading a tool comparison.
That caught my attention because my last article was called Foundry vs Hardhat: why Foundry won.
I argued that Foundry understood Solidity developers better. It was faster. Tests were written in Solidity. Fuzzing and cheatcodes were part of the core experience. Hardhat had the larger ecosystem, but Foundry had the better insight into what protocol engineers actually needed.
After publishing it, I wanted to see how much had changed.
The answer is: a lot.
I still think Foundry won the last era of Solidity tooling. But Hardhat learned from that loss, rebuilt the parts that held it back, and has become a serious competitor again. In some workflows, it may now be the better tool.
Hardhat did the hard thing
The easiest response to Foundry would have been a faster JavaScript test runner and a few official plugins.
Hardhat did something much more fundamental. It replaced its Ethereum simulation layer with EDR, a new runtime written in Rust and built on REVM.
This matters because the old performance comparison was architectural. Foundry executed Solidity tests through a native Rust toolchain. Hardhat ran JavaScript or TypeScript tests through Node.js, a client library, and a simulated network. Even if both tools compiled the same contracts, the testing path was completely different.
EDR changed that path.
Hardhat began shipping EDR in version 2.21 in 2024. Nomic Foundation reported that most projects saw at least a 2x improvement in test speed, with some seeing improvements of up to 10x. That was before the complete Hardhat 3 redesign.
Hardhat still uses Node.js for orchestration, configuration, plugins, and TypeScript workflows. But the performance-critical EVM execution is no longer a JavaScript implementation. Solidity tests run on an in-process Rust runtime without going through ethers.js or making a JSON-RPC request for every interaction.
The old claim that Hardhat is slow because Node.js is slow is no longer a useful explanation.
Solidity tests are now first-class
The biggest reason many protocol teams moved to Foundry was not raw speed. It was the ability to stay in Solidity.
Before Foundry, testing a Solidity contract usually meant switching languages:
- Write the contract in Solidity
- Write the test in JavaScript or TypeScript
- Send calls through ethers.js
- Handle asynchronous execution and JavaScript number types
- Translate EVM behavior into a different programming model
Foundry removed that context switch. A test was just another Solidity contract.
Hardhat 3 now does the same. Solidity tests are a first-class part of the framework, not a community plugin or compatibility layer bolted on afterward. It recognizes Foundry-style .t.sol files, runs setUp() before each test, supports forge-std, and follows the familiar test* function convention.
More importantly, Hardhat did not remove TypeScript testing to get there. It lets teams use both approaches in the same project:
- Solidity for fast unit tests, fuzzing, invariants, and contract-level behavior
- TypeScript for integrations, offchain services, deployments, bots, and multi-transaction scenarios
That combination is compelling. Foundry was right that Solidity is usually the best language for testing isolated Solidity logic. Hardhat is right that not every meaningful test stops at the contract boundary.
Fuzzing and invariants moved into the core
My previous argument was especially critical of Hardhat's security tooling.
Foundry made fuzz testing almost unavoidable. Add parameters to a test function and Forge generates inputs, explores edge cases, shrinks failures, and gives you a counterexample. Stateful invariant testing lets the runner execute randomized sequences of calls and continuously check properties that should never break.
Hardhat 3 now has both built in.
Its Solidity runner supports parameterized fuzz tests, stateful invariant campaigns, configurable run counts and depth, counterexample shrinking, fork testing, and per-test configuration. These features are implemented in EDR rather than delegated to an unrelated plugin.
The strategic gap has closed. Hardhat no longer treats fuzzing and invariant testing as specialist features that developers must assemble themselves.
That does not make the two implementations identical. Foundry has a longer track record, more battle-tested workflows, and the broadest security-focused community. But choosing Hardhat no longer means giving up the testing techniques that made Foundry attractive.
Cheatcodes came with it
Solidity-native testing works because cheatcodes give tests control over the environment.
You need to change msg.sender, move time forward, modify balances, fork a live chain, expect a revert, sign data, read files, or generate addresses. Foundry turned those operations into a coherent testing interface through vm cheatcodes.
Hardhat 3 supports most of that interface, including compatibility with common Foundry tests and forge-std. It also supports fork-mode Solidity tests, filesystem permissions, FFI when explicitly enabled, gas snapshots, and newer helpers such as EIP-712 cheatcodes.
There are still some unsupported Foundry cheatcodes, so compatibility is not perfect. Hardhat's own Foundry migration guide acknowledges this. But the fact that the official documentation now explains how to move a Foundry test suite into Hardhat tells you how much the competitive landscape has changed.
The performance gap is no longer obvious
My previous article cited a benchmark where Foundry compiled and ran tests in 1.44 seconds while Hardhat took 5.17 seconds. With caches enabled, the result was 0.45 seconds against 3.98 seconds.
Those numbers were real, but they came from an old comparison of Foundry Solidity tests against pre-EDR Hardhat JavaScript tests. They should not be used to describe Hardhat 3.
The two frameworks now have much more similar execution architectures. Both use native Rust components. Both can execute tests written in Solidity. Both avoid the JavaScript-to-RPC round trip for those tests.
Foundry may still be faster. Its CLI is extremely lean, it has less bootstrap overhead, and its entire workflow was designed around native Solidity development from the beginning. But I could not find a rigorous, reproducible, apples-to-apples benchmark showing a dramatic advantage over current Hardhat 3 across compilation, unit tests, fuzzing, invariants, coverage, and fork testing.
That is an important correction.
The honest claim today is not that Hardhat has definitely beaten Foundry on speed. It is that Hardhat has improved enough that speed alone is no longer an automatic reason to reject it. The 1inch migration is especially interesting in that context: a production DeFi team with demanding contract workflows is helping shape Hardhat 3 while moving projects onto it.
Hardhat kept the things Foundry never tried to replace
Hardhat did not become Foundry with an npm package. It kept the parts of its identity that were already valuable.
Its plugin system remains useful for teams with custom build, deployment, verification, and integration requirements. Dependencies can be managed through npm with lockfiles, semantic versions, and transitive dependencies, while Hardhat 3 also understands remappings.txt and Foundry-style project layouts.
Hardhat Ignition provides declarative deployments with resumability and idempotency. Verification can target Etherscan, Blockscout, and Sourcify. Gas reporting can produce aggregate statistics and JSON output for CI, including gas attribution through proxy chains. Coverage is built in and can generate HTML and LCOV reports.
Hardhat 3 also introduced native multichain simulation. Tests can run against Ethereum L1 or an OP Stack environment with chain-specific behavior instead of assuming every EVM chain behaves exactly like mainnet.
These are not features that make a five-line unit test better. They matter when a contract repository becomes part of a larger engineering organization.
That may explain why direct work with teams like 1inch and OpenZeppelin matters so much. Hardhat is optimizing for the point where a Solidity project stops being a collection of contracts and becomes production infrastructure.
Foundry still has real advantages
This is not a reversal where Hardhat wins and Foundry loses.
Foundry is still the cleaner choice for many Solidity-first teams. Forge is fast and focused. Cast is an excellent interface for interacting with chains. Anvil is simple and dependable. Chisel gives developers a Solidity REPL. forge script provides a powerful Solidity-native scripting and broadcasting workflow for which Hardhat has no direct equivalent.
Foundry also has the deeper culture around fuzzing, invariant testing, and protocol security. Its cheatcode surface is broader, its workflows are familiar to auditors, and it avoids bringing Node and npm into a repository that may not need either.
If I were starting a self-contained protocol repository with no meaningful offchain application layer, Foundry would still be my default.
But if the project includes TypeScript services, complex integrations, custom deployment infrastructure, chain-specific simulation, or internal tooling, Hardhat 3 now deserves a serious evaluation. The ability to use Solidity for low-level tests and TypeScript for realistic system tests is a strength, not a compromise.
Foundry won, and Hardhat listened
The most interesting part of Hardhat's comeback is that it validates Foundry's original insight.
Solidity developers wanted native speed. They wanted to test in Solidity. They wanted fuzzing, invariants, forks, cheatcodes, traces, gas reports, and coverage without constructing a fragile tower of plugins.
Foundry proved that those expectations were correct.
Hardhat could have defended the old model. Instead, it rewrote its execution engine in Rust, made Solidity testing first-class, brought security tooling into the runtime, added Foundry compatibility, and started working closely with teams migrating real production repositories.
That is what a good comeback looks like.
My previous conclusion was that Hardhat had the ecosystem advantage while Foundry had the insight, and insight won.
Today, Hardhat still has the ecosystem. But now it has absorbed the insight too.
Foundry won the argument. Hardhat may be winning its way back into the workflow.