Ethereum execution layer,
in TypeScript.

Modular, browser-ready protocol libraries — EVM, blocks, transactions, state — maintained by core contributors and open to the broader Ethereum dev community.


Built from the community

EthereumJS is one of the oldest JavaScript/TypeScript Ethereum stacks in the ecosystem — alongside Go Ethereum on the execution layer — with deep community roots going back to the early days of Ethereum.

The project grew out of the community, was nurtured for years within the Ethereum Foundation JavaScript team, and has since transitioned back to an independent community effort: a small core of maintainers, diversely funded, actively shipping protocol updates.

You don't need permission to get involved — open an issue, join a discussion, send a PR. Whether you're building dApps, researching EIPs, or just curious about how the protocol works in readable TypeScript, you're welcome here.


The stack

The ethereumjs-monorepo holds modular building blocks of the Ethereum execution layer — each package installable via npm, composable, and kept in sync through a shared @ethereumjs/common hardfork engine.

* @ethereumjs/client is deprecated — see the monorepo README for details.


See it in code

Run bytecode in the EVM

Five lines to instantiate an EVM and execute simple bytecode.

import { createEVM } from '@ethereumjs/evm'
import { hexToBytes } from '@ethereumjs/util'

const evm = await createEVM()
const res = await evm.runCode({
  code: hexToBytes('0x6001'), // PUSH1 01
})
console.log(res.executionGasUsed) // 3n

Run a transaction locally

Simulate an ETH transfer with the VM — no RPC node required.

import { Common, Hardfork, Mainnet } from '@ethereumjs/common'
import { createLegacyTx } from '@ethereumjs/tx'
import { createAccount, createAddressFromPrivateKey,
  createZeroAddress, hexToBytes } from '@ethereumjs/util'
import { createVM, runTx } from '@ethereumjs/vm'

const common = new Common({ chain: Mainnet,
  hardfork: Hardfork.Shanghai })
const vm = await createVM({ common })

const key = hexToBytes(`0x${'20'.repeat(32)}`)
const sender = createAddressFromPrivateKey(key)
await vm.stateManager.putAccount(sender,
  createAccount({ nonce: 0n, balance: 10n ** 18n }))

const tx = createLegacyTx({
  gasLimit: 21000n, gasPrice: 1_000_000_000n,
  value: 1n, to: createZeroAddress(),
}).sign(key)

const res = await runTx(vm, { tx })
console.log(res.totalGasSpent) // 21000n

Create a typed transaction

EIP-1559 fee-market transactions with a unified API across all tx types.

import { Common, Hardfork, Mainnet } from '@ethereumjs/common'
import { createFeeMarket1559Tx } from '@ethereumjs/tx'

const common = new Common({ chain: Mainnet,
  hardfork: Hardfork.London })

const tx = createFeeMarket1559Tx({
  gasLimit: 21000n,
  maxFeePerGas: 20_000_000_000n,
  maxPriorityFeePerGas: 1_000_000_000n,
  value: 1n,
  to: '0x000000000000000000000000000000000000dEaD',
}, { common })

console.log(tx.type) // 2
EVM code example in an editor

EVM usage in TypeScript

Colored EVM debug output

Built-in colored EVM debugging


Where it runs

dApp & tooling developers

Protocol-correct primitives in TypeScript — no reimplementing RLP, transaction formats, or EVM edge cases yourself.

Wallets & browser apps

Small bundles, WASM-free by default, runs in Node.js and the browser. Tree-shake what you need.

Researchers & EIP authors

Early EIP integrations — PeerDAS, binary tree state, Amsterdam hardfork — plus contributions to execution-spec-tests.

Educators & learners

A readable TypeScript codebase to explore how Ethereum execution actually works under the hood.

On the consensus side, Lodestar complements this stack with a TypeScript consensus client and SSZ implementations.

We've also helped close browser cryptography gaps in the ecosystem — BN254 for EVM precompiles, KZG for EIP-4844 and PeerDAS — with major contributions from @paulmillr (noble-curves, micro-eth-signer). ❤️


Join us

EthereumJS thrives on community contributions — bug reports, documentation, EIP prototyping, test cases, or a first PR. Come say hi.