web3.js vs ethers.js: a Comparison of Web3 Libraries
Tags: web3, ethereum, javascript, blockchain
Published: 2022-03-03 01:13:13

Both [web3.js](https://web3js.readthedocs.io/) and [ethers.js](https://docs.ethers.io) are JavaScript libraries that enable frontend apps to interact with the Ethereum blockchain, including smart contracts. If you're building an app that reads or writes to the blockchain from the client, you'll need to use one of these libraries. They have similar functionality, but an important question is how they will be maintained and grow with the emerging dapp ecosystem. 

## Quantitative comparison


|        | web3.js    | ethers.js  |
| ---------- | ---------- | ---------- |
| Date of first release  | Feb 2015 | Jul 2016 |
| GitHub stars  | 13.4k | 4k |
| GitHub contributors* | 16** | 1 |
| Bundle size*** | 590.6kB | 116.5kB |

_*GitHub contributors from March 1, 2021 to March 1, 2022_
_**16 contributors, but only 2 had more than 10 commits in the one year period_
_***Bundle size from [bundlephobia](https://bundlephobia.com), value of minified and gzipped package._

## API differences

While web3.js provides a single instantiated web3 object with methods for interacting with the blockchain, ethers.js separates the API into two separate roles. The `provider`, which is an anonymous connection to the ethereum network, and the `signer`, which can access the private key and sign the transactions. The ethers team [intended](https://medium.com/l4-media/announcing-ethers-js-a-web3-alternative-6f134fdd06f3) this separation of concerns to provide more flexibility to developers. 

### Side-by-side examples

Below are some examples of common functions a developer would include in their dapp. You'll see they offer the same functionality, with some slight differences of API.

#### Instantiating provider with MetaMask wallet

web3
`const web3 = new Web3(Web3.givenProvider);`

ethers
`const provider = new ethers.providers.Web3Provider(window.ethereum)`

#### Getting balance of account

web3
`const balance = await web3.eth.getBalance("0x0")`

ethers (supports ENS!)
`const balance = await provider.getBalance("ethers.eth")`

#### Instantiating contract

web3
`const myContract = new web3.eth.Contract(ABI, contractAddress);`

ethers
`const myContract = new ethers.Contract(contractAddress, ABI, provider.getSigner());`

#### Calling contract method

web3
`const balance = await myContract.methods.balanceOf("0x0").call()`

ethers
`const balance = await myContract.balanceOf("ethers.eth") `


## So which should I pick for my project?


Given the details above, web3.js looks like the go-to choice, with a longer history and more maintainers. However, ethers.js seems just as reliable and includes some differentiating perks such as size and additional features. Most other articles on this subject conclude that you could easily pick either, depending on what you're looking for. 

I too hesitate to recommend one over the other. But as the ecosystem evolves, it is important to me to pick the library that will be most flexible and supported by other libraries.

### Ecosystem factors

#### Which will be the most supported by open source libraries?

As the dapp ecosystem grows, which of the two libraries will be the most compatible with other open source libraries you want to bring into your app? 

In my limited experience, as this is still an emerging area for development, there are a couple libraries that require ethers.js to use the framework. Examples include [web3-react](https://www.npmjs.com/package/web3-react) and [NFT Swap SDK](https://docs.swapsdk.xyz). I have not yet seen libraries that require web3.js.

#### Which will have a solution for mocking for end-to-end testing?

Implementing end-to-end testing for web3 features is a challenge. This is partly because most tools, like [Cypress](https://www.cypress.io), run your tests in a Chromium browser that does not support browser extensions. Developers need an easy way to mock Ethereum providers or the web3/ethers instance to use inside their test environments. So far, I haven't seen any libraries that help solve this. But if there were a tool that helped mock providers for testing, and only worked with ethers for example, that would be enough for me to choose ethers over web3.  


Which library do you prefer, web3.js or ethers.js? Are there any tools in the ecosystem I'm overlooking? Let me know in the comments!