Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Why Run An Ethereum Node in JavaScript?

You know what would make solving all these problems trivially easy? If we just were able to use Foundry in the browser

That's what Fucory thought the day he started building Tevm โ€” putting the Foundry API in the browser, then growing from there. Tevm's use case is simply TypeScript + EVM.

We believe every TypeScript user of the EVM who installs Viem will also install Tevm alongside it in the future

  • ๐Ÿš€ Enhanced Performance โ€” Execute transactions locally with near-zero latency for gas estimation, simulation, and debugging.
  • ๐Ÿ’ป Browser Compatibility โ€” Enable offline capabilities, optimistic UI, and real-time simulations in dApps.
  • ๐Ÿ” Debug Superpowers โ€” Step through EVM execution opcode by opcode; inspect memory and stack.
  • ๐Ÿ› ๏ธ Familiar Developer Experience โ€” Works with viem, ethers, or any EIP-1193 compatible tool.

Performance & Efficiency

  • โšก Optimized fork mode โ€” Benchmarked to outperform Anvil at executing calls in forked mode via more efficient storage slot retrieval.
  • โšก Zero network latency โ€” Local EVM execution eliminates RPC round-trips for near-instant simulations and gas estimation.
  • Local-first gas estimation โ€” No loading spinner, no RPC credits burned.
  • ๐Ÿ”„ Powerful JS interop โ€” Simulate multiple transactions, plug directly into the EVM, or write custom contracts in JS.

Optimistic updates

Show users the expected state of their account โ€” pending transactions, state changes, or snappy UI with a pending icon. Tevm makes optimistic state simple.

// create a client in rebase mode so it updates optimistic state as new blocks come in
const client = createMemoryClient({
  fork: {
    transport: http("https://mainnet.optimism.io"),
    rebase: true,
  },
  common: optimism,
});
 
// When we send a transaction to the network send it to Tevm too
// We do not mine the transaction as we want it to just be in our mempool
const txHash = await client.sendRawTransaction(tx);
 
client.waitForTransactionReceipt({ hash: txHash }).then(() => {
  // remove the tx from optimistic state after it is included in chain
  const mempool = await client.transport.tevm.getTxPool();
  await mempool.removeTxByHash(txHash);
});
 
// continue to query the latest state by default
await client.getBalance({ address, blockTag: "latest" });
// or query optimistic state with 'pending' block tag
await client.getBalance({ address, blockTag: "pending" });

Real-World Performance Benefits

const gasEstimate0 = await client.estimateGas({ ... }) // ~200ms as it fetches state (unless you prewarmed the cache)
const gasEstimate0 = await client.estimateGas({ ... }) // ~Instant on future estimations with cache saved
const gasEstimate0 = await client.estimateGas({ ... }) // ~Instant on future estimations with cache saved

Because Tevm plugs directly into wagmi this works via useGasEstimate too.

Enhanced User Experiences

JavaScript-based EVM execution enables new categories of dApp features:

  • Maximally hackable โ€” Complete control including deep internals; supports almost any use case.
  • โšก Optimistic UI โ€” Show users the likely outcome of transactions before they're mined.
  • ๐Ÿ›ก๏ธ Reliable โ€” Near 100% test coverage; most reported bugs fixed in under 24 hours.
  • ๐Ÿงฎ Transaction Simulation โ€” Preview results of complex interactions before sending.
  • ๐Ÿ” Enhanced Privacy โ€” Process sensitive data locally without sending it to external services.

Top Tier Devx

Use the tools you already know

Tevm plugs directly into wagmi, viem, and ethers.

Interop with contracts effortlessly

The Tevm Bundler (optional) makes TypeScript aware of how to process and compile Solidity. It's in the same category as Wagmi CLI or Typechain, but more powerful:

  • Natspec on hover
  • Typesafe contracts
  • tRPC-like experience โ€” red underlines before you save the Solidity file
  • No external build tools โ€” plugs into your existing JS pipeline
  • Reads foundry config for remappings and lib

Import Solidity directly

The bundler has a compiler built in โ€” no precompilation needed:

import { MyContract } from "./MyContract.sol";
 
console.log(MyContract.abi);

You can import from node_modules or foundry projects. Tevm supports remappings, lib, and other advanced options. Unlike Foundry, Tevm supports node_module resolution by default.

Use contracts via address

If your contract is deployed, just reference it by address โ€” Tevm pulls the ABI at build time (even for unverified contracts):

// create a macro file for your contracts
import { client } from "./clients.js";
 
export const MyContract = await client.whatsabi(`0x...`);
// import your macro using tevm and Tevm will fetch your contracts at buildtime
import {MyContract} from './MyContract.js' as {type: 'tevm'}

Low level control of the EVM

Tools like anvil run in a separate process over HTTP. Tevm runs in memory with direct node access โ€” enabling programmability no other tool offers.

Run callbacks on every EVM step ๐Ÿ”ฌ

Step through EVM execution opcode by opcode, inspect memory and stack, and see exactly what happens in your contracts.

vm.evm.events.on("step", (data, next) => {
  console.log(
    `${data.pc.toString().padStart(5)}:`,
    `${data.opcode.name.padEnd(10)}`,
    `gas: ${data.gasLeft.toString().padStart(8)}`,
    `stack: ${data.stack.join(", ")}`,
  );
  next();
});

You can even modify EVM execution as it runs.

Mock EVM contracts with JavaScript contracts

Write contracts in JavaScript. Precompiles are like Foundry cheat codes, but instead of a standard library you write arbitrary JS. Works nicely with the Tevm Bundler:

import {
  defineCall,
  definePrecompile,
  createContract,
  createMemoryClient,
} from "tevm";
import { readFile } from "fs/promises";
 
const contract = createContract({
  address: `0x${"1234".repeat(10)}`,
  humanReadableAbi: ["function readFile(string fileName) returns string"],
});
 
const { precompile } = definePrecompile({
  contract,
  call: defineCall(contract.abi, {
    readFile: ({ args }) => {
      return {
        data: await readFile(args.fileName, "utf8"),
        gasUsed: 0n,
      };
    },
  }),
});
 
const memoryClient = createMemoryClient({
  precompiles: [precompile()],
});

Deterministic Testing ๐Ÿงช

Though built for application development, Tevm is great for testing too โ€” fully reproducible environments with complete control over blockchain state, time, and mining.

Solidity Imports

Tevm Bundler (optional) creates the best devx for Solidity files in TypeScript:

import { MyContract } from "./MyContract.sol";

JavaScript Ecosystem Integration

  • ๐Ÿ”ค TypeScript โ€” Type-safe contract interactions with full IntelliSense
  • โš›๏ธ UI Frameworks โ€” React, Vue, Svelte and other frontend libraries
  • ๐Ÿ—๏ธ Build Tools โ€” Vite, Webpack, ESBuild and other bundlers
  • ๐Ÿงช Testing โ€” Vitest support via Vite
  • ๐Ÿ”„ Runtimes โ€” Node.js, browsers, Electron, serverless functions
  • ๐Ÿ“ฆ NPM Ecosystem โ€” Millions of packages in the npm registry
  • ๐ŸŒ Web APIs โ€” Browser storage, WebSockets, service workers, and more

Ready to Get Started?

Next: Install Tevm ยท Create a Tevm Node ยท Run examples ยท GitHub