DEV Community

Deewakar Bora
Deewakar Bora

Posted on • Edited on

# Automating ethers.js v5 v6 Migration with Codemods

Ethers.js v5 has dozens of breaking changes when upgrading to v6. BigNumber is gone, provider names changed, utility functions moved, and contract patterns restructured. Doing this by hand across hundreds of files takes days.
I built a codemod toolkit using jssg (JavaScript ast-grep) that automates 95% of this migration with one command.

Quick Start

npx codemod ethers-v5-to-v6-codemod
Enter fullscreen mode Exit fullscreen mode

The Problem

Thousands of DeFi projects are still on ethers v5. The migration is painful not because any single change is hard, but because of sheer volume across hundreds of files. Simple regex fails on edge cases. The ecosystem needed a structural solution.

The Approach

12 jssg (JavaScript ast-grep) transforms orchestrated via workflow.yaml. jssg parses code into an AST — so replacements are structurally exact and never touch patterns inside string literals or comments. Zero false positives guaranteed.

What Gets Automated

  1. Utils functions — ethers.utils.formatEther, parseEther, formatUnits, arrayify, hexlify, and 10 more
  2. BigNumber to BigInt — BigNumber.from(x) to BigInt(x) with smart scope-aware detection
  3. Provider renames — ethers.providers.Web3Provider to ethers.BrowserProvider
  4. Crypto utils — keccak256, sha256, toUtf8Bytes, solidityKeccak256
  5. callStatic to staticCall — contract.callStatic.foo() to contract.foo.staticCall()
  6. Contract address — contract.address to contract.target
  7. Broadcast transaction — provider.sendTransaction(hex) to provider.broadcastTransaction(hex)
  8. Signature class — splitSignature, joinSignature, verifyMessage, recoverAddress
  9. Import cleanup — removes deprecated BigNumber and providers imports
  10. Gas price — provider.getGasPrice() to provider.getFeeData()
  11. Contract methods — estimateGas, populateTransaction, functions namespace
  12. Sub-package imports — @ethersproject/* to ethers

Real World Proof

Tested on thallo-io/ethers-js-cheatsheet — a real open source TypeScript DeFi project.
Result: 6 files transformed, 0 errors, 0 false positives, 1.266 seconds

Uniswap quote script before:

const amountIn = ethers.utils.parseEther("1");
const priceQuote = await uni.callStatic.quoteExactInputSingle(WETH9, DAI, fee, amountIn, sqrtPriceLimitX96);
console.log(ethers.utils.formatEther(priceQuote));
Enter fullscreen mode Exit fullscreen mode

After:

const amountIn = ethers.parseEther("1");
const priceQuote = await uni.quoteExactInputSingle.staticCall(WETH9, DAI, fee, amountIn, sqrtPriceLimitX96);
console.log(ethers.formatEther(priceQuote));
Enter fullscreen mode Exit fullscreen mode

Three patterns fixed automatically in one pass.

Coverage Breakdown

  • Automated by jssg transforms: ~95%
  • AI following AI-INSTRUCTIONS.md: ~4%
  • Manual review: ~1%

Links

Top comments (0)