Web3.js vs ethers.js in Blockchain / Solidity - Performance Comparison
Start learning this pattern below
Jump into concepts and practice - no test required
When working with blockchain libraries like Web3.js and ethers.js, it's important to understand how their operations scale as you interact with the blockchain.
We want to see how the time to complete tasks grows when using these libraries with larger inputs or more complex calls.
Analyze the time complexity of fetching multiple account balances using Web3.js and ethers.js.
// Using Web3.js
const balances = [];
for (let i = 0; i < accounts.length; i++) {
const balance = await web3.eth.getBalance(accounts[i]);
balances.push(balance);
}
// Using ethers.js
const balances = await Promise.all(
accounts.map(account => provider.getBalance(account))
);
This code fetches the balance for each account from the blockchain using two different libraries.
Look at what repeats as input grows.
- Primary operation: Fetching balance for each account.
- How many times: Once per account, so as many times as there are accounts.
As the number of accounts increases, the number of balance fetches grows the same way.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 balance fetches |
| 100 | 100 balance fetches |
| 1000 | 1000 balance fetches |
Pattern observation: The work grows directly with the number of accounts.
Time Complexity: O(n)
This means the time to get all balances grows in a straight line as you add more accounts.
[X] Wrong: "Using Promise.all in ethers.js makes the operation constant time regardless of input size."
[OK] Correct: Even though Promise.all runs requests in parallel, each balance still needs to be fetched, so total work still grows with the number of accounts.
Understanding how blockchain library calls scale helps you write efficient code and explain your choices clearly in conversations.
What if we batch multiple balance requests into a single call? How would the time complexity change?
Practice
Web3.js and ethers.js?Solution
Step 1: Understand library origins
Web3.js is an older, larger library designed for Ethereum interaction.Step 2: Compare library features
ethers.js is newer, designed to be lightweight and simpler to use.Final Answer:
Web3.js is larger and older, while ethers.js is lighter and simpler. -> Option DQuick Check:
Library size and age = A [OK]
- Thinking ethers.js only works on backend
- Confusing blockchain support (Bitcoin vs Ethereum)
- Believing ethers.js can't send transactions
Solution
Step 1: Recall ethers.js provider syntax
ethers.js usesethers.providers.JsonRpcProvider()to create a JSON RPC provider.Step 2: Identify correct syntax
const provider = new ethers.providers.JsonRpcProvider(); matches the correct ethers.js syntax; others mix Web3.js or incorrect classes.Final Answer:
const provider = new ethers.providers.JsonRpcProvider(); -> Option AQuick Check:
ethers.js provider creation = D [OK]
- Mixing Web3.js and ethers.js syntax
- Using Web3 classes with ethers.js
- Incorrect capitalization or namespaces
const ethers = require('ethers');
const provider = new ethers.providers.JsonRpcProvider();
(async () => {
const blockNumber = await provider.getBlockNumber();
console.log(blockNumber);
})();Solution
Step 1: Understand provider and method
TheJsonRpcProviderconnects to Ethereum andgetBlockNumber()returns the latest block number as a number.Step 2: Analyze async function output
The code logs the block number to console, so output is a number representing current block.Final Answer:
The current Ethereum block number as a number. -> Option CQuick Check:
getBlockNumber() returns number [OK]
- Expecting a string instead of number
- Thinking getBlockNumber() is missing
- Assuming provider is uninitialized
const Web3 = require('web3');
const web3 = new Web3();
(async () => {
const balance = await web3.eth.getBalance('0x123...');
console.log(balance);
})();Solution
Step 1: Check Web3 instance creation
Web3 requires a provider URL (like HTTP or WebSocket) when instantiated to connect to Ethereum.Step 2: Identify missing provider
The code createsnew Web3()without a provider, so calls likegetBalancewill fail.Final Answer:
Missing provider URL when creating Web3 instance. -> Option AQuick Check:
Web3 needs provider URL [OK]
- Thinking getBalance is not async
- Assuming address format is wrong
- Believing console.log can't print balance
Solution
Step 1: Identify correct method to send transaction
In ethers.js,signer.sendTransaction()sends a transaction and returns a transaction response.Step 2: Wait for transaction mining
Callingtx.wait()waits for the transaction to be mined before proceeding.Step 3: Confirm correct usage
const tx = await signer.sendTransaction(txData; await tx.wait(); console.log('Mined:', tx.hash); correctly awaits sending, then waits for mining, then logs the hash.Final Answer:
const tx = await signer.sendTransaction(txData); await tx.wait(); console.log('Mined:', tx.hash); -> Option BQuick Check:
sendTransaction + wait() = C [OK]
- Not awaiting sendTransaction()
- Using provider instead of signer to send
- Calling non-existent send() method
