ethers-v5-to-v6-codemod
A production-grade automated migration toolkit that transforms ethers.js v5 code to v6 using 12 jssg (JavaScript ast-grep) transforms. Covers ~95% of all real-world migration patterns with zero false positives.
Quick Start
bash# Run via Codemod registry npx codemod ethers-v5-to-v6-codemod # Or run workflow directly npx codemod workflow run -w workflow.yaml -t ./your-project
Tip: Always test on a copy of your project first.
What Gets Migrated
| Transform | What it does | Example |
|---|---|---|
transform1 | Utils functions | ethers.utils.formatEther → ethers.formatEther |
transform2 | BigNumber → BigInt | BigNumber.from("100") → BigInt("100") |
transform3 | Provider renames | ethers.providers.Web3Provider → ethers.BrowserProvider |
transform4 | Crypto utils | ethers.utils.keccak256 → ethers.keccak256 |
transform5 | callStatic | contract.callStatic.foo() → contract.foo.staticCall() |
transform6 | Contract address | contract.address → contract.target |
transform7 | Transactions | provider.sendTransaction(hex) → provider.broadcastTransaction(hex) |
transform8 | Signatures | ethers.utils.splitSignature(sig) → ethers.Signature.from(sig) |
transform9 | Import cleanup | Removes deprecated BigNumber and providers imports |
transform10 | Gas + hex utils | provider.getGasPrice() → provider.getFeeData() |
transform11 | Contract methods | contract.estimateGas.foo() → contract.foo.estimateGas() |
transform12 | Sub-package imports | @ethersproject/units → ethers |
Real-World Results
Tested on thallo-io/ethers-js-cheatsheet — a real open-source TypeScript project.
6 files transformed · 0 errors · 0 false positives
Example: Uniswap Quote Script
Before:
typescriptconst amountIn = ethers.utils.parseEther("1"); const priceQuote = await uni.callStatic.quoteExactInputSingle(WETH9, DAI, fee, amountIn, sqrtPriceLimitX96); console.log(ethers.utils.formatEther(priceQuote));
After:
typescriptconst amountIn = ethers.parseEther("1"); const priceQuote = await uni.quoteExactInputSingle.staticCall(WETH9, DAI, fee, amountIn, sqrtPriceLimitX96); console.log(ethers.formatEther(priceQuote));
Edge Cases
For the remaining ~5%, see AI-INSTRUCTIONS.md which documents 11 edge cases requiring manual or AI-assisted handling, including:
BigNumberTypeScript type annotations →bigintethers.utils.commifyreplacement (removed in v6)ethers.utils.fetchJson→FetchRequestclass rewrite- Custom provider subclass updates
contract.deployed()removalprovider.waitForTransaction→waitForTransactionReceipt
How It Works
jssg (JavaScript ast-grep) parses your source files into an Abstract Syntax Tree (AST). Each transform uses pattern matching to find specific v5 patterns and replaces them with their v6 equivalents, preserving your original formatting and comments.
Because transforms operate on the AST rather than raw text, replacements are structurally exact — they cannot accidentally match code inside string literals or comments.
Project Structure
textethers-v5-to-v6-codemod/ ├── workflow.yaml # Orchestrates all 12 transforms ├── codemod.yaml # Registry metadata ├── transform1.ts # Utils (formatEther, parseEther, constants, ...) ├── transform2.ts # BigNumber → BigInt ├── transform3.ts # Provider class renames ├── transform4.ts # Crypto utils (keccak256, sha256, toUtf8Bytes, ...) ├── transform5.ts # callStatic → staticCall ├── transform6.ts # contract.address → contract.target ├── transform7.ts # Transaction broadcast/serialize/parse ├── transform8.ts # Signature utilities ├── transform9.ts # Import/require cleanup ├── transform10.ts # Gas price + hex/address utilities ├── transform11.ts # estimateGas, populateTransaction, functions ├── transform12.ts # @ethersproject/* sub-package imports ├── AI-INSTRUCTIONS.md # Manual/AI edge case handling guide ├── CASE-STUDY.md # Hackathon case study ├── test-input.js # Test files for each transform └── test-input12.ts
Requirements
- Node.js 16+
- Codemod CLI (
npx codemod)
License
MIT