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
forkedmode 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 previews
Simulate the user's transaction with tevmCall before submitting it to a
network. The result includes return data, gas used, logs, and optional traces
without changing canonical state:
import { createMemoryClient, http } from 'tevm'
import { mainnet } from 'tevm/common'
const client = createMemoryClient({
common: mainnet,
fork: {
transport: http('https://ethereum-rpc.publicnode.com')({}),
blockTag: 20_000_000n,
},
})
await client.tevmReady()
const preview = await client.tevmCall({
from: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
to: '0x1111111111111111111111111111111111111111',
value: 1n,
createTrace: true,
})
console.log(preview.executionGasUsed, preview.errors)Real-World Performance Benefits
Fork-backed reads populate Tevm's local caches, so repeated simulations can reuse account code and storage already fetched from the upstream RPC.
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.
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 {
definePrecompile,
createContract,
createMemoryClient,
} from "tevm";
import { hexToBytes, stringToHex } from "tevm/utils";
const contract = createContract({
address: `0x${"1234".repeat(10)}`,
humanReadableAbi: ["function hello() returns (bytes)"],
});
const { precompile } = definePrecompile({
contract,
call: async () => ({
returnValue: hexToBytes(stringToHex("hello")),
executionGasUsed: 200n,
}),
});
const memoryClient = createMemoryClient({
customPrecompiles: [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

