Getting Started
These docs target tevm@1.0.0-rc.151.
Install
npm install tevm@1.0.0-rc.151 viemTevm re-exports the viem helpers used by the examples. Install viem separately only when your application imports directly from viem.
Run a Local Transaction
import {
createMemoryClient,
parseEther,
PREFUNDED_ACCOUNTS,
} from 'tevm'
const client = createMemoryClient({
miningConfig: { type: 'manual' },
})
const sender = PREFUNDED_ACCOUNTS[0].address
const recipient = '0x1111111111111111111111111111111111111111'
const { txHash } = await client.tevmCall({
from: sender,
to: recipient,
value: parseEther('1'),
addToMempool: true,
})
if (!txHash) throw new Error('transaction was not added to the txpool')
await client.tevmMine({ blockCount: 1 })
const receipt = await client.getTransactionReceipt({ hash: txHash })
const balance = await client.getBalance({ address: recipient })
console.log(receipt.status, balance)createMemoryClient() is synchronous. The first action initializes the node lazily. Use await client.tevmReady() when initialization itself should finish before a measurement or forked read.
What Just Happened?
createMemoryClientcreated an in-process Ethereum chain and a viem-compatible client.tevmCall({ addToMempool: true })executed the transfer and added its transaction to the txpool.tevmMine({ blockCount: 1 })built a canonical block.- viem actions read the receipt and final balance.
Without addToMempool, tevmCall is a simulation and does not change canonical state.
Install Contract Code
Use viem test actions to prepare state and public actions to query it.
import { createMemoryClient } from 'tevm'
import { SimpleContract } from 'tevm/contract'
const client = createMemoryClient()
const contract = SimpleContract.withAddress(
'0x2222222222222222222222222222222222222222',
)
await client.setCode({
address: contract.address,
bytecode: contract.deployedBytecode,
})
const value = await client.readContract({
address: contract.address,
abi: contract.abi,
functionName: 'get',
})
console.log(value)Fork an Existing Chain
The fork transport must be an EIP-1193 request function. Invoke the viem HTTP transport factory with ({}) when passing it directly.
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 balance = await client.getBalance({
address: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
blockNumber: 20_000_000n,
})
console.log(balance)Pin blockTag for reproducible tests. Local writes are stored in an overlay and never sent upstream.
Choose an API Surface
- Use MemoryClient with viem for most apps and tests.
- Use Ethers through the EIP-1193 provider surface.
- Use TevmNode for low-level runtime integrations.
- Use the bundler to import Solidity files into TypeScript.
Next: Architecture Overview · Mining Modes · Local Testing

