<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Deewakar Bora</title>
    <description>The latest articles on Forem by Deewakar Bora (@deewakar_bora_945a1188728).</description>
    <link>https://forem.com/deewakar_bora_945a1188728</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3875208%2F378aa2ee-e9ca-4644-bff0-22edb56e43b8.png</url>
      <title>Forem: Deewakar Bora</title>
      <link>https://forem.com/deewakar_bora_945a1188728</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/deewakar_bora_945a1188728"/>
    <language>en</language>
    <item>
      <title># Automating ethers.js v5 v6 Migration with Codemods</title>
      <dc:creator>Deewakar Bora</dc:creator>
      <pubDate>Sun, 12 Apr 2026 17:00:15 +0000</pubDate>
      <link>https://forem.com/deewakar_bora_945a1188728/-automating-ethersjs-v5-v6-migration-with-codemods-3l16</link>
      <guid>https://forem.com/deewakar_bora_945a1188728/-automating-ethersjs-v5-v6-migration-with-codemods-3l16</guid>
      <description>&lt;p&gt;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.&lt;br&gt;
I built a codemod toolkit using jssg (JavaScript ast-grep) that automates 95% of this migration with one command.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx codemod ethers-v5-to-v6-codemod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Approach
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Gets Automated
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Utils functions — ethers.utils.formatEther, parseEther, formatUnits, arrayify, hexlify, and 10 more&lt;/li&gt;
&lt;li&gt;BigNumber to BigInt — BigNumber.from(x) to BigInt(x) with smart scope-aware detection&lt;/li&gt;
&lt;li&gt;Provider renames — ethers.providers.Web3Provider to ethers.BrowserProvider&lt;/li&gt;
&lt;li&gt;Crypto utils — keccak256, sha256, toUtf8Bytes, solidityKeccak256&lt;/li&gt;
&lt;li&gt;callStatic to staticCall — contract.callStatic.foo() to contract.foo.staticCall()&lt;/li&gt;
&lt;li&gt;Contract address — contract.address to contract.target&lt;/li&gt;
&lt;li&gt;Broadcast transaction — provider.sendTransaction(hex) to provider.broadcastTransaction(hex)&lt;/li&gt;
&lt;li&gt;Signature class — splitSignature, joinSignature, verifyMessage, recoverAddress&lt;/li&gt;
&lt;li&gt;Import cleanup — removes deprecated BigNumber and providers imports&lt;/li&gt;
&lt;li&gt;Gas price — provider.getGasPrice() to provider.getFeeData()&lt;/li&gt;
&lt;li&gt;Contract methods — estimateGas, populateTransaction, functions namespace&lt;/li&gt;
&lt;li&gt;Sub-package imports — @ethersproject/* to ethers&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Real World Proof
&lt;/h2&gt;

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

&lt;p&gt;Uniswap quote script before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;amountIn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;priceQuote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;uni&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;callStatic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quoteExactInputSingle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WETH9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DAI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amountIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sqrtPriceLimitX96&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formatEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;priceQuote&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;amountIn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parseEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;priceQuote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;uni&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;quoteExactInputSingle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;staticCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WETH9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DAI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amountIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sqrtPriceLimitX96&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ethers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formatEther&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;priceQuote&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three patterns fixed automatically in one pass.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coverage Breakdown
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Automated by jssg transforms: ~95%&lt;/li&gt;
&lt;li&gt;AI following AI-INSTRUCTIONS.md: ~4%&lt;/li&gt;
&lt;li&gt;Manual review: ~1%&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/DeewakarBora/ethers-v5-to-v6-codemod" rel="noopener noreferrer"&gt;https://github.com/DeewakarBora/ethers-v5-to-v6-codemod&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Codemod registry: &lt;a href="https://app.codemod.com/registry/ethers-v5-to-v6-codemod" rel="noopener noreferrer"&gt;https://app.codemod.com/registry/ethers-v5-to-v6-codemod&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DoraHacks: &lt;a href="https://dorahacks.io/buidl/42646" rel="noopener noreferrer"&gt;https://dorahacks.io/buidl/42646&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>etherjs</category>
      <category>javascript</category>
      <category>blockchain</category>
      <category>codemod</category>
    </item>
  </channel>
</rss>
