ethers, wagmi, and connectkit represent three distinct layers of the Ethereum frontend stack. ethers is a low-level library for interacting with the Ethereum blockchain, handling providers, signers, and contract abstraction. wagmi is a collection of React Hooks that manages wallet state and interactions, simplifying the integration of Ethereum into React applications. connectkit is a UI toolkit that provides pre-built components for wallet connection flows, designed to work on top of wagmi. Together, they form a complete solution, but each can be evaluated based on the specific layer of abstraction a team needs to implement.
Building decentralized applications (dApps) on Ethereum requires handling wallet connections, network switching, and contract interactions. ethers, wagmi, and connectkit solve different parts of this puzzle. ethers provides the core logic to talk to the blockchain. wagmi wraps that logic in React Hooks for state management. connectkit provides the visual components for users to actually connect their wallets. Let's compare how they handle common engineering tasks.
ethers requires you to manually request access from the browser provider (like MetaMask).
accountsChanged yourself.// ethers: Manual connection
import { BrowserProvider } from "ethers";
async function connect() {
if (window.ethereum) {
await window.ethereum.request({ method: "eth_requestAccounts" });
const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const address = await signer.getAddress();
console.log("Connected:", address);
}
}
wagmi provides a hook to access connection state instantly.
// wagmi: Hook-based connection
import { useAccount } from "wagmi";
function Profile() {
const { address, isConnected, isLoading } = useAccount();
if (isLoading) return <div>Connecting...</div>;
if (isConnected) return <div>Address: {address}</div>;
return <div>Not connected</div>;
}
connectkit provides a pre-built button component.
// connectkit: UI Component
import { ConnectButton } from "connectkit";
function Navbar() {
return (
<nav>
<h1>My dApp</h1>
<ConnectButton /> {/* Handles all connection UI */}
</nav>
);
}
ethers uses a Contract instance to call read-only functions.
// ethers: Reading data
import { Contract } from "ethers";
const abi = ["function balanceOf(address) view returns (uint256)"];
const contract = new Contract(address, abi, provider);
const balance = await contract.balanceOf(userAddress);
console.log(balance.toString());
wagmi uses useReadContract to fetch data reactively.
// wagmi: Reading data
import { useReadContract } from "wagmi";
function Balance({ address }) {
const { data } = useReadContract({
address: contractAddress,
abi: contractAbi,
functionName: "balanceOf",
args: [address],
});
return <div>Balance: {data?.toString()}</div>;
}
connectkit does not handle contract logic directly.
wagmi hooks for data.// connectkit: Displaying identity
import { useConnectKit } from "connectkit";
function UserProfile() {
const { isSignedIn, address } = useConnectKit();
// Use wagmi hooks for actual contract data
return isSignedIn ? <div>User: {address}</div> : null;
}
ethers has no global config.
// ethers: Setup
import { BrowserProvider } from "ethers";
const provider = new BrowserProvider(window.ethereum);
// Use provider instance directly
wagmi requires a top-level WagmiProvider config.
// wagmi: Setup
import { createConfig, http } from "wagmi";
import { mainnet } from "wagmi/chains";
const config = createConfig({
chains: [mainnet],
transports: { [mainnet.id]: http() },
});
// Wrap app with WagmiProvider using this config
connectkit wraps the wagmi config with UI options.
wagmi config and API keys (for ENS/avatars).// connectkit: Setup
import { ConnectKitProvider } from "connectkit";
function App() {
return (
<WagmiProvider config={config}>
<ConnectKitProvider apiKey="..."> {/* Adds UI layer */}
<MyApp />
</ConnectKitProvider>
</WagmiProvider>
);
}
ethers is a mature, standalone library.
wagmi is the React standard.
viem for underlying logic (lighter than ethers).connectkit is a UI specialist.
wagmi.| Feature | ethers | wagmi | connectkit |
|---|---|---|---|
| Primary Role | Core Blockchain Logic | React State Management | UI Components |
| React Integration | Manual (None) | Built-in Hooks | Built-in Components |
| Wallet UI | Build Your Own | Build Your Own | Pre-built Modal/Button |
| Contract Calls | Manual Instance | Reactive Hooks | Via wagmi Hooks |
| Best For | Backend / Custom Frontends | React dApps | Fast UI Implementation |
These tools are not mutually exclusive — they are layers of a stack.
ethers is the engine. Use it if you need to talk to Ethereum without React or want full manual control.wagmi is the transmission. Use it to connect that engine to your React UI efficiently.connectkit is the dashboard. Use it when you want a professional-looking connection interface without the design work.For most modern React dApps, the standard architecture is wagmi + connectkit. You would only reach for raw ethers if you are writing backend scripts or have very specific provider requirements that hooks do not cover.
Choose connectkit if you want a polished, pre-built UI for connecting wallets (modals, buttons, profiles) without designing your own components. It is best suited for teams using wagmi who want to ship a professional connection flow quickly. It is not a logic library, so it must be paired with wagmi.
Choose ethers if you need full control over provider management, signing, and RPC calls without React abstractions. It is ideal for backend scripts, non-React frontends, or cases where you need to manage wallet state manually. Note that for new React projects, higher-level tools like wagmi (which now defaults to viem) are often preferred for DX.
Choose wagmi if you are building a React application and want type-safe hooks to manage wallet connections, network switching, and contract interactions. It handles the complex state management of Web3 for you. It is the standard choice for React-based dApps that need robust, programmatic control over the wallet experience.
ConnectKit is a powerful React component library for connecting a wallet to your dApp. It supports the most popular connectors and chains out of the box and provides a beautiful, seamless experience.
and much more...
Get started with a ConnectKit + wagmi + viem project by following the documentation here.
You can find the full ConnectKit documentation in the docs here.
You can find the full API Reference in the docs here.
There are various runnable examples included in this repository in the examples folder:
You can try out some ConnectKit examples directly in your browser through CodeSandbox:
Clone the ConnectKit project and install the necessary dependencies:
$ git clone git@github.com:family/connectkit.git
$ cd connectkit
$ yarn install
and start the code bundler:
$ yarn dev:connectkit
$ yarn dev:connectkit-next-siwe
and then simply select the example you'd like to run:
$ yarn dev:vite # Vite
$ yarn dev:nextjs # Next.js
$ yarn dev:nextjs-siwe # Next.js with SIWE
Before starting on anything, please have a read through our Contribution Guidelines.
Follow @aave on Twitter for the latest updates on ConnectKit.
See LICENSE for more information.