blockchainsv
Developer Tools & Infrastructure·July 30, 2026·15 min read

Anvil vs Hardhat Network: choosing your local testnet

A local testnet becomes visible to a team only when it starts wasting the team’s time. A test suite that used to finish during a coffee refill now takes half a minute. A mainnet fork behaves differently from the UI’s assumptions.

Anvil vs Hardhat Network: choosing your local testnet

A frontend engineer asks for an account to impersonate, a timestamp to move, and a transaction to be mined—and the local node answers in a slightly different dialect than the script expects.

That is the real shape of the Anvil vs Hardhat Network local testing decision. It is not a contest between “modern” and “legacy” tools. It is a question of where friction sits in our delivery loop: test execution, TypeScript integration, fork simulation, debugging, or state sync across a full DApp stack.

Anvil, bundled with Foundry, is a Rust local Ethereum node using the revm EVM implementation. Hardhat Network is Node.js-based and runs on @ethereumjs/vm. Those choices affect raw speed, but they also affect the workflows around the node. If we treat either one as a disposable black box, the decision gets muddled fast.

Rust versus Node.js is really about the feedback loop

The usual shorthand is accurate but incomplete: Anvil is fast because it is Rust; Hardhat Network is convenient because it lives close to JavaScript and TypeScript tooling.

For Solidity-heavy work, that distinction has immediate consequences. Foundry can compile contracts, execute tests, produce traces, and run fuzzing in one tightly integrated toolchain. Anvil belongs naturally in that loop. When the contract suite is the center of gravity, keeping the node, test runner, debugger, and deployment tooling in the same ecosystem removes a surprising amount of handoff friction.

Hardhat Network earns its place differently. Many production DApps already have their build logic, deployment scripts, task definitions, test fixtures, ABI generation, and frontend-adjacent helpers in TypeScript. For those teams, starting a Node-based local chain inside an existing Hardhat process can be less disruptive than moving workflow primitives into a second stack.

Here is the practical comparison.

ParameterAnvilHardhat Network
Runtime foundationRust, using revmNode.js, using @ethereumjs/vm
Natural homeFoundry projects and Solidity-first testingTypeScript-heavy full-stack projects
Test and compile paceTypically faster for iterative Solidity workUsually slower in larger contract suites
RPC compatibilityStandard Ethereum JSON-RPC plus anvil_* and evm_* methodsStandard Ethereum JSON-RPC plus Hardhat-specific methods
DebuggingSupports Solidity logging through forge-std/console.solBuilt-in Solidity console.log workflow
Mainnet forkingSupported through a remote RPC endpointSupported through a remote RPC endpoint
Large synthetic block jumpsMining cost rises with block counthardhat_mine has an optimized range-mining path
Ecosystem advantageFoundry tooling, fuzz tests, Solidity scriptsBroad JavaScript/TypeScript plugin ecosystem

The last row is where teams often make an unnecessarily dramatic choice. We do not need to declare one tool the winner for every repository. The best local testnet for Solidity depends on what we are trying to shorten.

If a protocol engineer is running a property test 10,000 times, a slow local loop is a tax on thought. If a product team is testing an embedded wallet flow through a TypeScript fixture system, breaking its existing test harness can cost more than the seconds saved at the EVM layer.

The useful local node is the one that makes the next correct change feel cheap.

The speed comparison: where Anvil changes the rhythm of testing

In practice, Foundry commonly compiles and runs tests around 2–5 times faster than a comparable Hardhat setup. For a medium project with roughly 50 tests, that can mean a Hardhat run in the 18–25 second range versus about 2–4 seconds in Foundry.

We should be cautious with benchmark theater here. Test speed depends on compiler settings, fixture design, forking, RPC latency, disk activity, cache state, and whether the suite is actually testing contracts or mostly orchestrating application behavior. Still, the shape of the difference matters. A suite that returns in a few seconds changes developer behavior.

With a 20-second loop, people batch changes. They edit a contract, modify three tests, change an event assertion, then wait. When something breaks, the failure has several possible causes. With a 3-second loop, we can make a narrow change and test it immediately. The debugging surface shrinks. That is not just a performance metric; it is a correctness advantage.

Anvil also fits especially well with Foundry’s fuzzing workflow. Running thousands of generated cases in seconds makes it reasonable to leave fuzzing active while developing a transfer accounting rule, liquidation edge case, or access-control boundary. In a smart contract codebase, the bugs that survive are often not the happy-path bugs. They live in the odd sequence: pause, upgrade, withdraw, re-enter through an external callback, then call the stale permission path.

A quick loop gives us room to test that sequence while the implementation is still fresh in our heads.

There is another distinction worth making. “Hardhat is slower” does not mean “Hardhat is slow enough to be unusable.” A small suite with a few integration tests may complete quickly regardless of the local node. The difference becomes painful when any of these are true:

1. The Solidity suite is growing faster than the application layer. Protocol repositories often accumulate regression tests, invariant tests, and fork scenarios faster than UI tests. The node is then on the critical path of every change.

2. The team relies on repeated fuzzing during implementation. A fuzz test that feels expensive gets postponed. A fuzz test that finishes quickly becomes part of normal development.

3. CI runs several contract jobs in parallel. Faster local execution does not cure poor CI design, but it reduces queue time and makes failed pull requests easier to turn around.

4. Developers are debugging state transitions rather than isolated calls. Re-running a long setup to inspect a one-line revert is the kind of daily annoyance that drains attention without showing up on a roadmap.

5. Scripts share the same contracts and configuration as the tests. Foundry’s cohesive workflow can reduce duplication between deployment validation and contract testing.

That said, we should not move a repository to Foundry because a benchmark chart looks satisfying. Migration creates its own costs: rewritten tests, different assertion idioms, new conventions for fixtures, and changed expectations around scripts. The speed benefit is strongest when we design around it rather than bolting it onto an inherited setup.

Mining mechanics: the detail that can reverse the answer

Local chains are not only transaction executors. They are time machines. We use them to advance timestamps, cross epoch boundaries, trigger vesting cliffs, roll staking rewards forward, and test what happens after a governance delay. This is where an apparently straightforward local blockchain testnet comparison gets more interesting.

Both tools expose EVM-level methods for manipulating runtime state. Anvil supports custom anvil_* and evm_* namespaces, and it provides compatibility aliases used by other developer environments. For example, an impersonation workflow can use Anvil’s method directly or a familiar alias such as hardhat_impersonateAccount. That compatibility matters in mixed repositories: scripts do not need to be rewritten merely because the local node changed underneath them.

But block mining is not identical.

For a large number of blocks, Hardhat Network’s hardhat_mine is designed to run in nearly constant time by representing much of the requested range as synthetic blocks and mining the relevant final blocks. Anvil’s anvil_mine work scales linearly with the number of blocks requested. If our test advances a few blocks, that distinction is background noise. If it jumps through a huge emission schedule or simulates a long-lived vault, it can become the decisive factor.

This catches teams by surprise because Anvil tends to win the broader speed conversation. Yet a workload is not a slogan. If our suite does “mine 500,000 blocks, then inspect the final state,” Hardhat’s implementation may be the more appropriate tool for that specific test.

We can avoid turning that detail into tribal preference by separating test intent:

  • Use timestamp changes when the contract’s logic is time-based. If a vesting contract checks block.timestamp, advancing time is closer to the business rule than manufacturing a mountain of blocks.
  • Use modest block increments when the logic depends on block numbers. This keeps tests readable and avoids hiding assumptions inside giant mining calls.
  • Reserve massive mining jumps for contracts that truly use block height as a long-term clock. Mining a large range as a stand-in for “time passed” is often a test smell.
  • Test block-sensitive edge cases on the same local engine used in CI. A node swap should not quietly alter the semantics of the scenario we claim to cover.

Mainnet forking is another shared strength, with shared risk. Anvil can fork a remote network state through a fork URL, and Hardhat Network supports the same broad workflow. Forks are enormously valuable when we need to reproduce an integration against a live pool, token contract, proxy, or account state. They are also easy to misuse.

A fork test is only as stable as the block context and upstream RPC access behind it. Pin the fork block where repeatability matters. Keep the test’s purpose narrow. And do not confuse a successful fork interaction with a complete production readiness signal. Our DApp still has to survive wallet behavior, RPC throttling, indexing lag, and user-driven transaction ordering.

That wider environment is one reason engineering teams sometimes follow macroeconomic decisions: systems change behavior when stability is prioritized over speed. The same tension is visible in the case for policy stability during an ECB rate decision, though a local Ethereum node gives us a much friendlier feedback loop than a central bank does.

Debugging is part of the product experience too

A local node is developer infrastructure, but its quality eventually reaches the user journey. When contract state is difficult to inspect, teams ship more tentative interfaces. When a revert is hard to reproduce, error handling gets generic. When a test environment cannot impersonate a meaningful account or recreate a forked position, the frontend receives less realistic data until late in the release cycle.

That is why the debugging experience deserves more weight than it usually gets in a speed comparison.

Hardhat’s Solidity console.log has been a familiar comfort for JavaScript-oriented teams. It is built into the workflow, it is easy to reach for, and it helps when we need to inspect a value in a failing test without reworking the test structure. Anvil supports Solidity logging through the forge-std/console.sol library. The outcome is similar, but the surrounding ergonomics feel different if the team has spent years in Hardhat.

This is not a trivial preference. Tool familiarity affects whether developers add observability early or postpone it. Still, console logs should be temporary scaffolding, not the permanent architecture of diagnosis. For contract behavior that matters, we want tests that state the intended outcome in a way a future maintainer can read:

  • the expected emitted event and its arguments;
  • the exact custom error or revert condition;
  • balances before and after the state transition;
  • the actor whose permissions are being exercised;
  • the fork block and external state that make the scenario meaningful;
  • the invariant that must remain true after a sequence of calls.

Once those assertions exist, traces become explanations rather than rescue equipment.

Anvil’s RPC compatibility is particularly useful here. A frontend integration test may already depend on Hardhat-flavored methods for account impersonation or balance setup. Because Anvil provides aliases across familiar namespaces, we can often keep the test helper API stable while changing the local execution engine. That is graceful degradation at the tooling layer: the application test does not need to care which node fulfilled the state manipulation, as long as the contract behavior and RPC expectations remain consistent.

A faster test is helpful; a reproducible failure is what lets us fix the user-facing bug.

The TypeScript ecosystem is not an inconvenience to outgrow

Foundry’s rise has sometimes created a false story: Solidity developers use Anvil, while Hardhat survives only in older repositories. Production teams are messier than that, thankfully.

Hardhat remains a sensible center for projects where TypeScript is doing real work rather than wrapping a few deployment commands. Consider a DApp with generated client types, custom Hardhat tasks, deployment scripts that integrate with a multisig workflow, test fixtures shared with backend services, and a frontend team that knows the project’s TypeScript helpers by muscle memory. In that environment, Hardhat Network is not an obstacle. It is an established interface between people and the system.

The question is whether it should also carry the entire load of high-volume contract testing.

For some teams, yes. A coherent single-toolchain workflow has value. The test suite may be small enough that execution speed is not the bottleneck, while plugin availability and team familiarity keep releases moving. For others, the contract layer has become complex enough that the single-stack ideal starts producing avoidable waiting.

We can diagnose that moment without ideology. Look at the last few painful bugs. Did they come from:

  • a Solidity invariant that was not fuzzed enough;
  • a deployment script that drifted from the contract test setup;
  • a frontend state-sync issue caused by local-chain resets;
  • an integration test that needed custom TypeScript orchestration;
  • a fork scenario that was too slow or too brittle to run regularly;
  • a developer avoiding the full suite because it takes too long?

The answer tells us where to invest. It is entirely possible for Hardhat to remain the application integration hub while Anvil becomes the execution engine for faster contract-focused work.

A hybrid setup is often the least dramatic—and best—choice

The useful bridge here is the @foundry-rs/hardhat-anvil plugin. It allows Hardhat projects to start and stop an Anvil instance automatically when running Hardhat tests or scripts. That gives us a path to adopt Anvil’s local-node performance without asking every TypeScript test, deployment task, and frontend fixture to change language at once.

This approach works particularly well when a team has accumulated healthy Hardhat conventions but needs faster EVM execution. We preserve the existing project shape, then place Anvil behind the workflows where it removes friction.

A deliberate rollout can look like this:

1. Measure the current suite by category. Separate unit tests, fork tests, deployment validations, frontend integration tests, and any block-heavy simulations. A single headline runtime does not reveal where the time goes.

2. Move one contract-heavy test path first. Start with tests that have minimal TypeScript-specific orchestration and enough repetition for speed gains to be felt. Do not begin with the most fragile mainnet fork.

3. Keep RPC helpers node-agnostic where possible. Wrap impersonation, balance assignment, mining, timestamp changes, and snapshots behind project helpers. This protects the test suite from vendor-shaped method names.

4. Validate semantic behavior, not only runtime. Compare events, reverts, balances, and storage-relevant outcomes across the old and new local setup. Fast execution is not worth a subtle mismatch in the test environment.

5. Document the exceptions. If giant block-range simulations stay on Hardhat because hardhat_mine is a better fit, say so in the repository. Future contributors should see a design choice, not a mysterious inconsistency.

6. Make the developer command boring. Whether the local process launches Hardhat Network or Anvil, the team should have one predictable entry point for common workflows. Infrastructure only helps when it lowers cognitive load.

This hybrid path also gives us room to evaluate Foundry on its own merits. Once the team is comfortable with Anvil, it may choose to introduce Forge tests for new Solidity modules, particularly where fuzzing and fast iteration matter. Or it may retain Hardhat’s test runner while using Anvil only as the local node. Both are legitimate end states.

The goal is not tool purity. The goal is a repository where a developer can reproduce an issue, inspect state, run the relevant tests, and ship a fix before the thread in their head disappears.

Choose the local node that protects momentum

For an Anvil vs Hardhat Network local testing decision, start with the bottleneck we can name.

Choose Anvil as the default local engine when contract testing is central, suites are becoming slow, fuzzing is a daily tool, and the team benefits from Foundry’s tight Solidity workflow. The reported 2–5× improvement in many test-and-compile loops is meaningful because it changes how frequently we verify assumptions.

Keep Hardhat Network at the center when the repository’s value lives in its TypeScript integration layer, its plugins, its shared fixtures, and its full-stack developer experience. Its optimized handling of very large synthetic block ranges can also make it the better fit for particular block-height simulations.

And when the honest answer is “both,” let’s use both. Anvil can run underneath Hardhat workflows, familiar RPC patterns can remain in place, and migration can happen where it pays for itself.

The local testnet is not an invisible detail. It shapes how quickly we find contract errors, how confidently the frontend handles chain state, and how much patience our team has left for the hard parts of Web3 UX. Pick the node that gives that patience back.

FAQ

Is Anvil always faster than Hardhat Network?
Anvil is typically 2–5 times faster for compiling and running Solidity tests. However, performance depends on factors like compiler settings, fixture design, and whether the suite is testing contract logic or orchestrating application behavior.
Which tool is better for testing time-based or block-based contract logic?
Both tools support state manipulation, but Hardhat Network’s `hardhat_mine` is better for large synthetic block jumps. For time-based logic, it is generally better to advance timestamps rather than mining massive amounts of blocks.
Can I use Anvil if my project is already built on Hardhat?
Yes, you can use the `@foundry-rs/hardhat-anvil` plugin to run an Anvil instance automatically within your existing Hardhat workflow, allowing you to improve performance without a full migration.
Does switching to Anvil break my existing test scripts?
Anvil provides compatibility aliases for common methods, such as `hardhat_impersonateAccount`, which helps maintain stability. As long as your RPC helpers are node-agnostic, you can often switch engines without rewriting your test suite.
How do I decide if I should migrate to Foundry?
Migration is recommended if your Solidity suite is growing faster than your application layer, if you rely heavily on repeated fuzzing, or if your current test loop is causing developers to batch changes due to slow execution.

By Chloe Redfern