Ethereum
JavaScript / TypeScript
JavaScript has two mature libraries for talking to Ethereum: web3.js, the original, and ethers.js, the leaner modern option. (viem is a third, increasingly popular choice, but the examples here cover the two classics.) Both are actively maintained and both speak the same Ethereum JSON-RPC under the hood. For a new project, start with ethers.js v6 — its TypeScript types are written by hand rather than generated, the tree-shakeable build keeps a browser bundle small, and the BrowserProvider / JsonRpcProvider split maps cleanly onto MetaMask versus a backend connection to chain 1.
Both web3.js and ethers.js are under active development. For new Ethereum work, ethers.js v6 is the safer default — first-class TypeScript types and a noticeably smaller bundle when shipping to the browser.
Web3.js
web3.js is the original Ethereum JavaScript API and still the one most tutorials and older dApps are written against. Install it with npm install web3, then construct new Web3('https://ethereum.therpc.io/YOUR_API_KEY') — passing the URL string lets web3.js build its own HTTP provider, so a balance read is just web3.eth.getBalance(address) returning wei that web3.utils.fromWei turns into ETH.
- GitHub: https://github.com/web3/web3.js
- Docs: https://web3js.readthedocs.io/
- Complete coverage of the Ethereum JSON-RPC API
- WebSocket transport for
eth_subscribe(newHeads, logs, pending txs) - Contract interaction from ABIs, including ERC-20 and ERC-721
- ENS resolution for
.ethnames - One of the largest communities and the most third-party examples
Ethers.js
ethers.js takes a more compact, modular approach and ships TypeScript types as part of the core, not a separate package. Install with npm install ethers. For a server or script, wrap the endpoint in a JsonRpcProvider: new ethers.JsonRpcProvider('https://ethereum.therpc.io/YOUR_API_KEY'). From there provider.getBalance(address) returns a bigint of wei and ethers.formatEther renders it as a human ETH string — no decimal juggling.
- GitHub: https://github.com/ethers-io/ethers.js/
- Docs: https://docs.ethers.org/
- Hand-written TypeScript types shipped in the core package
- Smaller, tree-shakeable bundle for browser dApps
- Careful key handling and a strict, predictable API surface
- ENS resolution built in
- A large, well-maintained test suite tracking Ethereum behavior
TypeScript Support
Neither library needs a @types/* companion — both bundle their declarations, so a fresh npm install gives you typed access to Ethereum out of the box. In practice that means your editor autocompletes provider.getBalance and flags a wrong argument before you run anything, while the types double as inline docs for which RPC methods exist and what they return. The snippet below types a transaction shape so a missing to or a string where a bigint belongs fails at compile time, not on mainnet.
Node.js Usage
On the server, both libraries run the same way against the Ethereum endpoint regardless of module system. Use require() if your project is CommonJS or import if it's ESM — the connection code is identical, only the loading syntax differs. This is the setup you'd use for an indexer, a webhook that watches Ethereum logs, or any backend that signs transactions away from the browser.
Browser Usage
In the browser, import either library as an ES module and let a bundler like Vite or webpack package it for the page. There's a key distinction here: use a JsonRpcProvider pointed at the endpoint for read-only data, but when you need the user to sign — connect their wallet, send ETH, approve a token — go through new ethers.BrowserProvider(window.ethereum). That hands signing to MetaMask or another injected wallet, so the private key stays in the extension and your dApp only ever sees the signed result.