Web3 Development · 5 min read ·
Learn how to build modern Web3 frontends using wagmi and viem with type-safe reads, writes, wallet UX, and production-ready patterns.
Web3 frontend development has matured: users expect the same responsiveness, safety, and polish as any fintech app. The old pattern—sprinkling ethers.js calls through React components and hoping wallet state behaves—doesn’t hold up at scale.
Today, the most productive (and defensible) stack for EVM app frontends is wagmi for React hooks + wallet orchestration, and viem for fast, type-friendly Ethereum JSON-RPC interactions. Together they give you a clean architecture: viem handles the protocol details; wagmi handles React state, caching, connectors, and UX ergonomics.
A good Web3 frontend needs to solve more than “send a transaction.” You need:
wagmi is effectively the “React Query for Ethereum” plus connector management. viem is a lower-level toolkit that is strict about types and encoding/decoding, and it’s notably fast. wagmi uses viem internally; the combination is consistent and future-proof.
Opinionated take: if your frontend is React (Next.js, Vite, Remix), wagmi + viem is the path of least regret for EVM.
Assume a Next.js (App Router) or Vite React app. You’ll typically install:
wagmiviemIn wagmi v2, you create a config with chains, transports, and connectors. A good baseline includes:
Practical advice: treat RPC selection like infrastructure, not a dev convenience. Free public RPCs are fine for prototypes, not for revenue.
The biggest unlock is to avoid mixing “wallet state” with “protocol reads.”
This separation lets your app render meaningful data even before a user connects a wallet, which improves conversion.
Contract reads are where most frontends quietly accumulate bugs: wrong ABI fragments, incorrect argument order, BigInt handling, and decoding surprises.
With wagmi, the common pattern is useReadContract (and useReadContracts for batching). You provide:
addressabifunctionNameargschainId (optional but recommended when multi-chain)Key details that make this production-grade:
abitype/wagmi cli or your build tooling). Avoid hand-editing.BigInt end-to-end. viem returns bigint for uints. Don’t coerce to number except for UI formatting.useReadContracts reduces RPC roundtrips dramatically.Real example: a lending UI might batch totalSupply, borrowRate, userBorrowBalance, and userCollateralValue in one request per block.
Many teams overuse event subscriptions early. Subscriptions are fragile across providers and browsers. A more reliable approach:
watch: true patterns)If you truly need events (e.g., chatty order books, realtime fills), use WebSocket transport and be deliberate about fallback behavior.
Opinionated take: optimistic UI beats event subscriptions for most DeFi flows. Show the pending state immediately, then reconcile on confirmation.
A professional-grade Web3 frontend does not “just call write.” It:
wagmi supports this flow cleanly. The usual pattern is:
useSimulateContract to validate inputs and generate a requestuseWriteContract to submituseWaitForTransactionReceipt to track confirmationWhy simulate? Because it moves failure earlier—before the user signs. That improves trust and reduces support tickets (“I paid gas and nothing happened”).
Concrete example: in an ERC-20 approve + deposit flow:
approve(spender, amount)deposit(amount)Yes, it’s more steps. It’s also how you avoid edge-case reverts due to allowances, paused markets, or stale parameters.
Your app should detect the wrong network and offer a one-click switch. wagmi’s chain configuration makes this straightforward.
Wallet state is messy: users change accounts, lock wallets, or their mobile session drops. wagmi handles connector state and exposes consistent hooks so your UI doesn’t devolve into conditional spaghetti.
Users need to know:
Make the transaction hash a first-class citizen in your state model, and always provide an explorer link per chain.
useReadContracts) aggressively for performance. For complex dashboards, consider a backend indexer, but multicall gets you far.Practical rule: don’t block initial render on wallet connection. It’s a conversion killer.
wagmi + viem is the modern baseline for EVM Web3 frontends because it forces a clean separation of concerns: viem for correct, type-safe protocol calls and wagmi for React-native state, caching, and wallet UX. If you build around simulation-first writes, batched reads, and explicit transaction lifecycle UI, you’ll end up with an app that feels like real product software—not a hackathon demo.
If you’re scaling a DeFi or onchain app, invest early in these patterns. Frontend reliability is not a “nice-to-have” in Web3; it’s part of your security posture and your growth strategy.