Web3 Development · 5 min read ·
Build fast, type-safe Web3 frontends using wagmi hooks and viem clients, with best practices for reads, writes, and chain switching.
Web3 frontend development is where product reality meets blockchain reality: wallets are flaky, networks change, RPCs rate-limit, and users expect the app to feel as smooth as any Web2 product. The best modern stack for Ethereum and EVM chains is wagmi (React hooks + state + connectors) paired with viem (type-safe, low-level EVM client).
If you’re still using older “everything-and-the-kitchen-sink” libraries, you’re likely paying in bundle size, unclear abstractions, and runtime errors that TypeScript could have caught. wagmi + viem is opinionated in the right places and composable everywhere else.
wagmi gives you React-friendly primitives: connect wallet, track account state, sign messages, simulate and send transactions, read contracts, watch events. It integrates cleanly with caching solutions like TanStack Query.
viem is the engine underneath: it handles transport, encoding/decoding, signing, and contract interactions with strong typing. It’s designed to be tree-shakeable and explicit—meaning you choose your transport, chains, and clients, which matters for performance and reliability.
In practice:
A solid wagmi setup starts with defining supported chains and transports. In production, you want redundancy (multiple RPCs) and clear separation between public reads and wallet writes.
Key decisions:
http() is simplest; fallback() improves resilience across RPC providers.Practical recommendation: keep reads fast and cheap with a public client; keep writes tied to the user’s wallet client.
Your “Connect Wallet” flow is not a button—it’s a state machine. wagmi exposes this state clearly, which helps you build a UX that doesn’t lie.
What to handle explicitly:
Connectors to consider:
Opinionated take: if you’re building a consumer dapp, don’t ship with only Injected. WalletConnect is table stakes.
Reads should be:
wagmi’s contract read hooks work best when paired with an ABI typed via tooling like abitype or codegen from your contract artifacts. With viem’s strong typing, your function names and argument types are validated at compile time.
Patterns that scale:
useTokenBalance, useVaultPosition).chainId when your app supports multiple networks.Example scenario: a token approval UI.
(owner, spender)You’ll end up with a UI that never guesses.
The fastest way to ship a buggy dapp is to call writeContract directly and hope for the best. A better flow is:
wagmi supports this flow cleanly, and viem’s simulation makes failures explainable. This is especially important for:
Practical insight: show users actionable errors. Don’t display raw “execution reverted.” Map common failures (insufficient balance, slippage, paused contract) to clear messages.
Multi-chain UX is where many frontends fall apart. Users don’t think in chain IDs—they think in “the app works.”
Best practices:
wagmi’s network hooks expose chain, chains, and switching methods so you can build a predictable flow.
Polling every 3 seconds is an easy habit—and a costly one at scale. For reactive UX (positions updating after a swap, new deposits, order fills), use events where possible.
Approaches:
Caveat: event subscriptions depend on your RPC/provider quality. For production-grade apps, consider a fallback strategy:
A Web3 frontend is only as good as its RPCs and caching strategy.
Concrete guidance:
fallback() transports across at least two providers (e.g., Alchemy + public RPC).Security and correctness notes:
approve as a security-sensitive action: consider “approve exact” vs “infinite approval” and be explicit in the UI.A proven structure for medium-to-large dapps:
lib/chains.ts: supported chains + contract addresses per chainlib/wagmi.ts: wagmi config, connectors, transportslib/abi/: versioned ABIs (or generated types)features/<domain>/hooks/: domain hooks wrapping wagmi reads/writesfeatures/<domain>/components/: UI components consuming those hooksThis avoids the “hooks everywhere” spaghetti and makes audits and refactors easier.
wagmi + viem is the current best-in-class approach for EVM Web3 frontends because it forces clarity: explicit clients, explicit chains, and type-safe contract interactions—without fighting React. The winning pattern is consistent across most apps:
If you adopt these practices early, you’ll ship a dapp that feels fast, fails gracefully, and stays maintainable as your protocol—and your user base—grows.