Core Concepts
Clients, actions, transports, typed ABIs, unit helpers, and the value/address primitives everything else is built from.
Third-party documentation. This is independently authored analysis of the public Viem codebase — not the official docs, and not reviewed or endorsed by the Viem team.
Core Concepts
A handful of primitives cover nearly all viem usage.
Chains and units
Chain objects (viem/chains) carry chain id, RPC defaults, and explorer URLs — they are data, not singletons, so multi-chain apps just construct multiple clients. Values are bigint wei everywhere; parseEther/parseUnits convert human strings on the way in, formatUnits on the way out. This kills the classic floating-point precision bug class at the type level.
Typed ABIs
ABI items are plain objects; declaring them with as const turns them into literal types. Viem ships ready-made literals for common standards (erc20Abi, erc721Abi). Contract actions validate function names and argument tuples against the ABI's type, then encode with its own encoder — no external schema language.
Reads vs. writes vs. simulations
readContract maps to eth_call (stateless, free, effects discarded). simulateContract runs the same encoding through a simulation request to preview results, gas, and revert reasons before spending anything. writeContract actually submits a transaction. The three share one ABI surface deliberately.
Errors as values
Viem raises structured error classes (network, RPC, contract-revert with decoded custom-error data). Catching a revert means catching a typed object carrying the decoded error name and arguments — a large quality-of-life shift from string-matching raw revert payloads.
Accounts
privateKeyToAccount (local signing), JSON-RPC accounts (delegated to wallets), and mnemonic-derived HD accounts share one interface, so application code doesn't care where signatures come from.
