JavaScript-native Ethereum runtime for TypeScript apps, tests, and tools.
Tevm 1.0 is now available on the npm rc dist-tag.
npm install tevm@rc viemThe release candidate includes the new block, mining, receipt, txpool, JSON-RPC, tracing, and viem-compatible client work that replaces the older pre-1.0 README examples. The npm latest tag may still point at the older next series, so use tevm@rc when trying the current 1.0 release candidate.
Tevm runs an Ethereum execution environment inside JavaScript. Use it as an in-memory devnet, a forked-chain simulator, an EIP-1193 provider, a viem-compatible client, or a lower-level EVM toolkit.
It runs in Node, Bun, browsers, serverless functions, edge runtimes, and desktop apps without Docker or a background chain process.
- Fork any EVM chain locally: run calls against mainnet, L2s, L3s, or appchains while overriding accounts, storage, and block context.
- Use viem actions directly:
createMemoryClientincludes viem public, wallet, and Anvil-style test actions. - Control mining behavior: choose automatic, manual, or interval mining and decide when pending transactions become canonical blocks.
- Inspect real execution: collect traces, receipts, logs, access lists, created addresses, and block-level results from local execution.
- Import Solidity in TypeScript: use Tevm bundler plugins to import Solidity contracts with ABI, bytecode, and type-safe helpers.
- Run in the browser: build local-first dapps, optimistic UIs, demos, and tests where a separate RPC node would be too heavy.
- Extend the EVM: add custom precompiles, predeploys, decorators, and low-level runtime packages when you need direct control.
Create a local in-memory chain, add a transaction to the mempool, mine it, and read the receipt.
import { createMemoryClient, parseEther } from "tevm";
const client = createMemoryClient({
miningConfig: { type: "manual" },
});
await client.tevmReady();
const alice = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266";
const bob = "0x1111111111111111111111111111111111111111";
await client.tevmSetAccount({
address: alice,
balance: parseEther("1"),
});
const { txHash } = await client.tevmCall({
from: alice,
to: bob,
value: parseEther("0.1"),
addToMempool: true,
});
if (!txHash) {
throw new Error("Transaction was not added to the mempool");
}
await client.tevmMine({ blockCount: 1 });
const receipt = await client.getTransactionReceipt({ hash: txHash });
const balance = await client.getBalance({ address: bob });
console.log(receipt.status, balance);Tevm can fork through any EIP-1193 or viem transport. Set common when you know the chain to avoid an extra chain-id lookup.
import { createMemoryClient, http, parseAbi } from "tevm";
import { optimism } from "tevm/common";
const client = createMemoryClient({
common: optimism,
fork: {
transport: http("https://mainnet.optimism.io"),
blockTag: "latest",
},
miningConfig: { type: "manual" },
});
await client.tevmReady();
const abi = parseAbi(["function balanceOf(address) view returns (uint256)"]);
const balance = await client.readContract({
address: "0x4200000000000000000000000000000000000042",
abi,
functionName: "balanceOf",
args: ["0x0000000000000000000000000000000000000000"],
});
console.log(balance);- Blocks and canonical chain state: Tevm now mines blocks instead of only mutating state snapshots. Calls that create transactions are pending until mined; cheat methods such as
tevmSetAccountstill update canonical state immediately. - Mining modes: configure
miningConfigwithmanual,auto, orintervalbehavior. Useclient.tevmMine()or viem's Anvil-compatibleclient.mine()to advance the chain. - Txpool and receipts: transactions can enter the mempool, be mined into blocks, and then be queried through viem actions or JSON-RPC methods such as
eth_getTransactionReceipt. - Historical block tags:
blockTagworks for forked history and locally mined Tevm blocks. - State and block overrides:
tevmCall,tevmContract,tevmDeploy, andeth_callcan run with temporary account, storage, and block overrides. - Execution tracing: use
createTraceon calls andtraceConfigon debug APIs to inspect EVM execution for tests, debuggers, and profilers. - Synchronous client creation:
createMemoryClient()andcreateTevmNode()return synchronously;client.tevmReady()andnode.ready()are available when you want to eagerly wait for initialization. - EIP-1193 request support:
requestnow follows the EIP-1193 shape. The previous low-level request helpers are available assendandsendBulk. - Stable decorators: extend
TevmNodewithtevmActions,ethActions,tevmSend, andrequestEip1193. - Broader JSON-RPC compatibility: Tevm supports more Ethereum, Anvil, Ganache, and Hardhat-compatible RPC methods for viem test-client workflows.
- State persistence: persist and hydrate in-memory client state with synchronous storage using
createSyncStoragePersister. - Runtime packages: the monorepo now includes Tevm-native block, blockchain, tx, txpool, receipt-manager, state, VM, and utility packages.
createMemoryClient is the easiest entry point. It returns a viem client with Tevm actions and Anvil-style test actions already installed.
import { createMemoryClient } from "tevm";
const client = createMemoryClient({
miningConfig: { type: "auto" },
});
await client.tevmReady();
await client.tevmSetAccount({ address: "0x0000000000000000000000000000000000000001", balance: 1n });
await client.getBlockNumber();createTevmNode gives lower-level access to the runtime and decorator model.
import { createTevmNode } from "tevm";
import { requestEip1193, tevmActions } from "tevm/decorators";
const node = createTevmNode({ miningConfig: { type: "manual" } })
.extend(tevmActions())
.extend(requestEip1193());
await node.ready();
const chainId = await node.request({ method: "eth_chainId" });Tevm bundler plugins let TypeScript import Solidity modules directly.
import { createMemoryClient } from "tevm";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20.sol";
const client = createMemoryClient();
const token = ERC20.withAddress("0x0000000000000000000000000000000000000000");
const balance = await client.tevmContract(
token.read.balanceOf("0x0000000000000000000000000000000000000001"),
);tevm.json is optional in the RC series. Use package-specific bundler docs for Vite, Webpack, Bun, esbuild, rspack, and other integrations.
The tevm package re-exports the most common runtime APIs. Individual packages remain available when you want smaller imports or lower-level control.
| Package | Purpose |
|---|---|
tevm |
Main batteries-included package |
@tevm/memory-client |
viem-compatible in-memory Ethereum client |
@tevm/node |
Low-level Tevm node and decorator runtime |
@tevm/actions |
Tevm actions, JSON-RPC handlers, and debug APIs |
@tevm/decorators |
Client extensions for actions, EIP-1193, and events |
@tevm/block, @tevm/blockchain, @tevm/tx, @tevm/txpool |
Chain, block, transaction, and mempool internals |
@tevm/receipt-manager |
Receipt storage and lookup |
@tevm/state, @tevm/vm, @tevm/evm |
State manager and execution internals |
@tevm/sync-storage-persister |
Synchronous persistence for browser or embedded storage |
Contributions are welcome. See CONTRIBUTING.md for local setup, testing, and pull-request guidance.
Tevm is MIT licensed. See LICENSE for details.