> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://v3.viem.sh/api/mcp` to find what you need.

# Why Viem

Viem is a type-safe TypeScript interface for Ethereum. It provides high-level primitives
for applications, libraries, and coding agents that need predictable behavior without hiding how
Ethereum works.

## The Problem

High-level Ethereum interfaces often trade between four concerns:

* [**Developer Experience**](#developer-and-agent-experience)
* [**Stability**](#stability)
* [**Bundle Size**](#bundle-size)
* [**Performance**](#performance)

Improving one can make another worse.

Viem treats all four as core requirements. Its explicit Ethereum building blocks combine strong
types, composable behavior, and escape hatches at every important boundary.

## Developer and Agent Experience

Viem's APIs and documentation are structured to be predictable for both developers and coding
agents. The same repeated shapes support consistent discovery, explanations, generation, and review.

### Predictable APIs

The core modules, [Clients](/docs/clients), [Actions](/docs/actions), [Accounts](/docs/accounts), and
[Transports](/docs/transports), each represent a distinct domain.

Namespaces group each domain's functions and capabilities. Developers can use
editor autocomplete, while coding agents can search the repository for related APIs.

```ts twoslash
// @noErrors
import { Actions } from 'viem'

Actions.transaction.
//                  ^|
```

Applications can opt into concise methods with [`publicActions`](/docs/actions/public) and
[`.extend()`](/docs/clients/create#extending-a-client).

:::code-group
```ts twoslash [example.ts]
// @noErrors
import { client } from './viem.config'

const blockNumber = await client.block.getNumber()
// @log: 19868020n
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
// @noErrors
import { Client, http, publicActions } from 'viem'
import { mainnet } from 'viem/chains'

export const client = Client.create({
  chain: mainnet,
  transport: http(),
}).extend(publicActions())
```
:::

#### Standalone Action

The Actions namespace also keeps dependencies explicit.
[`Actions.block.getNumber`](/docs/actions/public/block/getNumber) receives its Client directly.

:::code-group
```ts twoslash [example.ts]
// @noErrors
import { Actions } from 'viem'
import { client } from './viem.config'

const blockNumber = await Actions.block.getNumber(client)
// @log: 19868020n
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
// @noErrors
import { Client, http } from 'viem'
import { mainnet } from 'viem/chains'

export const client = Client.create({
  chain: mainnet,
  transport: http(),
})
```
:::

Both forms use the same Action implementation. Choose the shape that makes ownership clearest for
your project.

### Agent-Readable Documentation

API pages use consistent sections for usage, parameters, return values, errors, and examples.
Twoslash checks TypeScript examples against the current Viem source.

These checks can reveal API drift before publication.

The site also publishes the same documentation in formats agents can consume directly:

* **Agent-aware Markdown:** Viem detects requests from coding agents and automatically serves each
  page as Markdown. For explicit access, open
  [`why-viem.md`](https://v3.viem.sh/docs/why-viem.md) or request `Accept: text/markdown`.
* **LLM indexes:** coding agents can use [`llms.txt`](https://v3.viem.sh/llms.txt) as a compact page
  index or [`llms-full.txt`](https://v3.viem.sh/llms-full.txt) as the full documentation corpus.
* **MCP:** connect to [`https://v3.viem.sh/api/mcp`](https://v3.viem.sh/api/mcp) to search documentation
  and inspect source across Viem, Wagmi, Ox, and Tempo.

These are direct representations of the docs and source, which gives agents better context than a
browser page or isolated code snippet alone.

[Set Up the Viem MCP Server](/docs/agents)

### Types That Follow Your Inputs

Viem uses strict types and type inference. API inputs determine parameter and return types, which
provides precise autocomplete.

The type system also rejects invalid combinations before a request is sent.

Pass an ABI to [`Actions.contract.read`](/docs/actions/public/contract/read), for example, and the
editor suggests valid function names, then narrows the arguments and return value for the selected
function.

```ts twoslash
// @noErrors
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abis } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abis.erc20

await Actions.contract.read(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: '
//               ^|
})
```

Type information is preserved as Clients are extended and APIs are composed.

## Stability

Ethereum applications depend on predictable behavior across networks and runtimes. Viem targets
near-100% test coverage across unit, type, integration, browser, and runtime tests.

Integration tests run against local and forked Ethereum nodes.

## Bundle Size

Viem publishes side-effect-free ESM so compatible bundlers can remove unused modules. Domain
entrypoints and optional decorators keep a base Client focused on required behavior.

Applications do not need to include every Action or environment-specific helper.

## Performance

Viem builds encoding, decoding, hashing, and Ethereum data primitives on
[Ox](https://oxlib.sh)-backed utilities.
Synchronous work stays synchronous where possible, while network and cryptographic work crosses
asynchronous boundaries only when required.

The same modular design that supports tree shaking also keeps hot paths small and lets applications
choose the Transport, batching, polling, and caching policies that fit their workload.

## Next Steps

<Cards>
  <Card title="Getting Started" description="Create a Client and make your first Ethereum request." icon="lucide:rocket" to="/docs" />

  <Card title="Installation" description="Install Viem with your preferred package manager or runtime." icon="lucide:package" to="/docs/installation" />

  <Card title="Create a Client" description="Compose a Chain, Transport, and optional Account." icon="lucide:blocks" to="/docs/clients/create" />
</Cards>
