Ethereum L1 Protocol Stack and EVM in TypeScript
TypeScript
2,758
7,627 commits
updated Oct 12, 2026
Modular TypeScript libraries for Ethereum execution-layer protocol work.
Composable, spec-tested building blocks for the Ethereum execution layer: EVM execution, transactions, blocks, state, tries, and chain configuration. Use them in Node.js or the browser — tree-shakeable, Noble crypto by default, WASM-free unless you opt in.
tx, block, mpt, statemanager, and friends instead of pulling in a full clientMaintained by former members of the Ethereum Foundation JavaScript team and the broader Ethereum community.
| Fork | Status |
|---|---|
| Osaka | Mainnet today — stable on npm |
| Amsterdam | In development - see status here |
| Goal | Start here | npm package |
|---|---|---|
| Run a signed tx, replay a block, or build a block | packages/vm | @ethereumjs/vm |
| Execute bytecode, custom opcodes, or precompiles | packages/evm | @ethereumjs/evm |
| Create, sign, or parse transactions | packages/tx | @ethereumjs/tx |
| Blocks, headers, withdrawals | packages/block | @ethereumjs/block |
| Persistent chain storage | packages/blockchain | @ethereumjs/blockchain |
| Merkle proofs and trie tooling | packages/mpt | @ethereumjs/mpt |
| Chain config and hardfork parameters | packages/common | @ethereumjs/common |
flowchart TD
start[What_are_you_building]
start --> txRules[Tx_and_block_rules]
start --> bytecode[Bytecode_only]
start --> chainData[Chain_storage_or_types]
txRules --> vmPkg["@ethereumjs/vm"]
bytecode --> evmPkg["@ethereumjs/evm"]
chainData --> blockPkg["@ethereumjs/block / blockchain"]
Install the VM (includes EVM, tx, and state wiring):
npm install @ethereumjs/vm @ethereumjs/common @ethereumjs/tx @ethereumjs/util
Run a simple signed transfer against an in-memory state (adapted from packages/vm/examples/runTx.ts):
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.Prague })
const vm = await createVM({ common })
const senderKey = hexToBytes(`0x${'20'.repeat(32)}`)
const sender = createAddressFromPrivateKey(senderKey)
await vm.stateManager.putAccount(sender, createAccount({ nonce: 0n, balance: BigInt(1e18) }))
const tx = createLegacyTx({
gasLimit: 21000n,
gasPrice: 1_000_000_000n,
value: 1n,
to: createZeroAddress(),
}).sign(senderKey)
const res = await runTx(vm, { tx })
console.log(res.totalGasSpent) // 21000n
For bytecode-only execution use @ethereumjs/evm (examples). For blob (EIP-4844) transactions you need a separate KZG library — see KZG setup in the tx README.
Active packages (published in sync on v10; see scripts/release-npm.ts):
| Package | Role | Docs |
|---|---|---|
@ethereumjs/rlp | RLP encode/decode | README |
@ethereumjs/util | Bytes, accounts, addresses, signatures | README |
| Package | Role | Docs |
|---|---|---|
@ethereumjs/common | Chains, hardforks, EIP parameters | README |
@ethereumjs/genesis | Genesis state for known chains | README |
| Package | Role | Docs |
|---|---|---|
@ethereumjs/tx | Legacy, 1559, 2930, 4844, 7702 transactions | README |
@ethereumjs/block | Blocks, headers, withdrawals | README |
| Package | Role | Docs |
|---|---|---|
@ethereumjs/mpt | Merkle Patricia Trie and proofs | README |
@ethereumjs/binarytree | EIP-7864 binary tree | README |
@ethereumjs/statemanager | Merkle, RPC, and binary-tree state backends | README |
| Package | Role | Docs |
|---|---|---|
@ethereumjs/evm | EVM interpreter, opcodes, precompiles | README |
@ethereumjs/vm | runTx, runBlock, block building | README |
| Package | Role | Docs |
|---|---|---|
@ethereumjs/blockchain | Canonical chain storage and validation | README |
| Package | Role | Notes |
|---|---|---|
@ethereumjs/e2store | Era / Era1 / E2HS archive formats | Deprecation under consideration |
@ethereumjs/ethash | Ethash PoW verification | Maintained for deps; not in active release round |
flowchart BT
rlp --> util --> common
common --> tx & block & mpt & genesis
mpt --> block & statemanager
tx --> block --> vm
statemanager --> evm --> vm
block --> blockchain
Full responsibility matrix, execution flow (runBlock → runTx → evm), and release notes: ARCHITECTURE.md.
Releases: active development on master (v10). Maintenance branches and breaking-release policy: DEVELOPER.md § Releases.
Clone and build:
git clone https://github.com/ethereumjs/ethereumjs-monorepo.git
cd ethereumjs-monorepo
git submodule update --init
npm install
Tooling, CI, conventions, and release process: DEVELOPER.md · CONTRIBUTING.md.
| Package | Role |
|---|---|
@ethereumjs/client | Full execution client (deprecated) |
@ethereumjs/devp2p | devp2p networking (deprecated) |
@ethereumjs/wallet | Key management helpers (deprecated) |
Still on npm for migration reference; do not start new projects on these packages.
The EthereumJS GitHub organization is maintained by the former Ethereum Foundation JavaScript team and contributors. Join Discord for questions and follow the Code of Conduct.
Related: Lodestar — TypeScript consensus client and SSZ tooling for the Ethereum consensus layer.
Most packages are MPL-2.0 licensed; see each package folder for its license file.
(top 24 of 28)
789 followers · starred Feb 2021
1,148 followers · starred Aug 2020
216 followers · starred May 2024
282 followers · starred Sep 2021
Ethereum L1 Protocol Stack and EVM in TypeScript
TypeScript
2,758
7,627 commits
updated Oct 12, 2026
Modular TypeScript libraries for Ethereum execution-layer protocol work.
Composable, spec-tested building blocks for the Ethereum execution layer: EVM execution, transactions, blocks, state, tries, and chain configuration. Use them in Node.js or the browser — tree-shakeable, Noble crypto by default, WASM-free unless you opt in.
tx, block, mpt, statemanager, and friends instead of pulling in a full clientMaintained by former members of the Ethereum Foundation JavaScript team and the broader Ethereum community.
| Fork | Status |
|---|---|
| Osaka | Mainnet today — stable on npm |
| Amsterdam | In development - see status here |
| Goal | Start here | npm package |
|---|---|---|
| Run a signed tx, replay a block, or build a block | packages/vm | @ethereumjs/vm |
| Execute bytecode, custom opcodes, or precompiles | packages/evm | @ethereumjs/evm |
| Create, sign, or parse transactions | packages/tx | @ethereumjs/tx |
| Blocks, headers, withdrawals | packages/block | @ethereumjs/block |
| Persistent chain storage | packages/blockchain | @ethereumjs/blockchain |
| Merkle proofs and trie tooling | packages/mpt | @ethereumjs/mpt |
| Chain config and hardfork parameters | packages/common | @ethereumjs/common |
flowchart TD
start[What_are_you_building]
start --> txRules[Tx_and_block_rules]
start --> bytecode[Bytecode_only]
start --> chainData[Chain_storage_or_types]
txRules --> vmPkg["@ethereumjs/vm"]
bytecode --> evmPkg["@ethereumjs/evm"]
chainData --> blockPkg["@ethereumjs/block / blockchain"]
Install the VM (includes EVM, tx, and state wiring):
npm install @ethereumjs/vm @ethereumjs/common @ethereumjs/tx @ethereumjs/util
Run a simple signed transfer against an in-memory state (adapted from packages/vm/examples/runTx.ts):
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.Prague })
const vm = await createVM({ common })
const senderKey = hexToBytes(`0x${'20'.repeat(32)}`)
const sender = createAddressFromPrivateKey(senderKey)
await vm.stateManager.putAccount(sender, createAccount({ nonce: 0n, balance: BigInt(1e18) }))
const tx = createLegacyTx({
gasLimit: 21000n,
gasPrice: 1_000_000_000n,
value: 1n,
to: createZeroAddress(),
}).sign(senderKey)
const res = await runTx(vm, { tx })
console.log(res.totalGasSpent) // 21000n
For bytecode-only execution use @ethereumjs/evm (examples). For blob (EIP-4844) transactions you need a separate KZG library — see KZG setup in the tx README.
Active packages (published in sync on v10; see scripts/release-npm.ts):
| Package | Role | Docs |
|---|---|---|
@ethereumjs/rlp | RLP encode/decode | README |
@ethereumjs/util | Bytes, accounts, addresses, signatures | README |
| Package | Role | Docs |
|---|---|---|
@ethereumjs/common | Chains, hardforks, EIP parameters | README |
@ethereumjs/genesis | Genesis state for known chains | README |
| Package | Role | Docs |
|---|---|---|
@ethereumjs/tx | Legacy, 1559, 2930, 4844, 7702 transactions | README |
@ethereumjs/block | Blocks, headers, withdrawals | README |
| Package | Role | Docs |
|---|---|---|
@ethereumjs/mpt | Merkle Patricia Trie and proofs | README |
@ethereumjs/binarytree | EIP-7864 binary tree | README |
@ethereumjs/statemanager | Merkle, RPC, and binary-tree state backends | README |
| Package | Role | Docs |
|---|---|---|
@ethereumjs/evm | EVM interpreter, opcodes, precompiles | README |
@ethereumjs/vm | runTx, runBlock, block building | README |
| Package | Role | Docs |
|---|---|---|
@ethereumjs/blockchain | Canonical chain storage and validation | README |
| Package | Role | Notes |
|---|---|---|
@ethereumjs/e2store | Era / Era1 / E2HS archive formats | Deprecation under consideration |
@ethereumjs/ethash | Ethash PoW verification | Maintained for deps; not in active release round |
flowchart BT
rlp --> util --> common
common --> tx & block & mpt & genesis
mpt --> block & statemanager
tx --> block --> vm
statemanager --> evm --> vm
block --> blockchain
Full responsibility matrix, execution flow (runBlock → runTx → evm), and release notes: ARCHITECTURE.md.
Releases: active development on master (v10). Maintenance branches and breaking-release policy: DEVELOPER.md § Releases.
Clone and build:
git clone https://github.com/ethereumjs/ethereumjs-monorepo.git
cd ethereumjs-monorepo
git submodule update --init
npm install
Tooling, CI, conventions, and release process: DEVELOPER.md · CONTRIBUTING.md.
| Package | Role |
|---|---|
@ethereumjs/client | Full execution client (deprecated) |
@ethereumjs/devp2p | devp2p networking (deprecated) |
@ethereumjs/wallet | Key management helpers (deprecated) |
Still on npm for migration reference; do not start new projects on these packages.
The EthereumJS GitHub organization is maintained by the former Ethereum Foundation JavaScript team and contributors. Join Discord for questions and follow the Code of Conduct.
Related: Lodestar — TypeScript consensus client and SSZ tooling for the Ethereum consensus layer.
Most packages are MPL-2.0 licensed; see each package folder for its license file.
(top 24 of 28)
789 followers · starred Feb 2021
1,148 followers · starred Aug 2020
216 followers · starred May 2024
282 followers · starred Sep 2021