<?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: Patrick Amey-Jones</title>
    <description>The latest articles on Forem by Patrick Amey-Jones (@patrick_ameyjones_0379c1).</description>
    <link>https://forem.com/patrick_ameyjones_0379c1</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%2F3754903%2Fd753c7e6-bc3f-4923-95eb-6f5db543b113.png</url>
      <title>Forem: Patrick Amey-Jones</title>
      <link>https://forem.com/patrick_ameyjones_0379c1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/patrick_ameyjones_0379c1"/>
    <language>en</language>
    <item>
      <title>We scanned 4,500 GitHub repos. Here's what developers are actually migrating to.</title>
      <dc:creator>Patrick Amey-Jones</dc:creator>
      <pubDate>Mon, 30 Mar 2026 18:34:46 +0000</pubDate>
      <link>https://forem.com/patrick_ameyjones_0379c1/we-scanned-4500-github-repos-heres-what-developers-are-actually-migrating-to-59ln</link>
      <guid>https://forem.com/patrick_ameyjones_0379c1/we-scanned-4500-github-repos-heres-what-developers-are-actually-migrating-to-59ln</guid>
      <description>&lt;h1&gt;
  
  
  We scanned 4,500 GitHub repos. Here's what developers are actually migrating to.
&lt;/h1&gt;

&lt;p&gt;Developer tools come and go. Blog posts tell you what you &lt;em&gt;should&lt;/em&gt; use. GitHub history tells you what people are &lt;em&gt;actually&lt;/em&gt; doing.&lt;/p&gt;

&lt;p&gt;We built IndieStack to catalog developer tools — auth, payments, databases, email, the whole stack. As part of that, we scraped package.json files across thousands of public GitHub repos, tracking dependency changes over time. The result: 422 confirmed migration paths across 4,535 repos, plus 93,111 verified tool combinations showing what gets used together in production.&lt;/p&gt;

&lt;p&gt;Here's what the data shows.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vitest is eating the testing ecosystem
&lt;/h2&gt;

&lt;p&gt;The single strongest migration signal in our dataset: &lt;strong&gt;Jest to Vitest, in 37 repos&lt;/strong&gt;. Add Mocha to Vitest (13 repos) and you have the dominant story in JavaScript testing right now.&lt;/p&gt;

&lt;p&gt;It's not hard to see why. Vitest runs natively in ESM, integrates with Vite's transform pipeline, and its API is close enough to Jest that migration is mostly mechanical. For projects already on Vite, it's a free lunch: one build tool, one config, one mental model.&lt;/p&gt;

&lt;p&gt;Mocha, meanwhile, is losing ground in both directions — to Vitest (13), to Jest (12), and even to Ava (10). That last one is interesting. Ava has been around since 2014 and is far from new, but it's still pulling developers away from Mocha in 2025. Mocha's decline isn't about one competitor winning — it's about an older paradigm (callback-based, no native ESM, verbose config) losing relevance broadly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Webpack is losing. Vite is winning. The story is more nuanced than that.
&lt;/h2&gt;

&lt;p&gt;Webpack → Vite showed up 18 times. Webpack → Rollup showed 12. Rollup → Vite showed 6. Webpack → esbuild showed 5.&lt;/p&gt;

&lt;p&gt;The simple read: Webpack is the loser. But look at where those repos are landing. Vite absorbs migrations not just from Webpack but from Rollup and esbuild too. It's not just a faster bundler — it's becoming the default dev environment. Rollup and esbuild were often intermediate steps (faster builds, simpler config), but Vite wraps both of them and adds HMR, dev server, and first-class framework integrations. The final destination for most of these migrations is Vite.&lt;/p&gt;

&lt;p&gt;One caveat: our dataset skews toward frontend-heavy repos. Webpack still dominates enterprise and SSR-heavy setups. These numbers reflect the direction of travel for greenfield projects, not the installed base.&lt;/p&gt;




&lt;h2&gt;
  
  
  The security swap nobody talks about
&lt;/h2&gt;

&lt;p&gt;18 repos migrated from &lt;code&gt;bcrypt&lt;/code&gt; to &lt;code&gt;bcryptjs&lt;/code&gt;. That's the second-highest migration count in our entire dataset, tied with webpack → vite.&lt;/p&gt;

&lt;p&gt;This one doesn't get the conference talks. bcrypt (the native Node binding) has historically caused install headaches on certain architectures — especially ARM and Alpine Linux containers. bcryptjs is a pure JavaScript implementation: slower in benchmarks, zero native compilation. But for most web apps hashing a password on login, the difference is microseconds. The trade-off is obvious once you've hit it, which explains the quiet, consistent migration.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cypress → Playwright: the E2E shift is real but slow
&lt;/h2&gt;

&lt;p&gt;Cypress to Playwright showed up 7 times; Cypress to Vitest (unit testing as a substitute for E2E) showed 5 times. That's 12 repos moving away from Cypress.&lt;/p&gt;

&lt;p&gt;The reasons are well-documented: Playwright runs in multiple browsers natively, handles async better, and Microsoft is actively developing it. But 12 repos is not a flood. Cypress has a massive installed base and excellent DX. The migration cost for E2E tests is high — these are slow, brittle, hard to rewrite. We'd expect this number to grow slowly over the next two years, not spike.&lt;/p&gt;




&lt;h2&gt;
  
  
  The quiet signals
&lt;/h2&gt;

&lt;p&gt;Two smaller migrations worth noting:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Moment → Day.js (6 repos).&lt;/strong&gt; Moment officially went into maintenance mode in 2020. Five years later, repos are still migrating. The long tail of moment usage in production is real.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recoil → Jotai (5 repos).&lt;/strong&gt; Facebook's Recoil never achieved the adoption the React team expected, and Jotai — lighter, no string-keyed atoms, smaller API surface — is picking up the converts. In state management, the trend is consistently toward less abstraction, not more.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this means
&lt;/h2&gt;

&lt;p&gt;If you're starting a project in 2025, the migration data points to a clear default stack for JS tooling: &lt;strong&gt;Vite for bundling, Vitest for tests, Playwright for E2E&lt;/strong&gt;. These aren't just the trendy choices — they're where repos are actually landing after paying the migration cost to move away from something else.&lt;/p&gt;

&lt;p&gt;The IndieStack migration database now covers 422 migration paths. You can browse them, see what tools your stack has in common with 4,500 real repos, and check whether the tools you're using are gaining or losing ground.&lt;/p&gt;

</description>
      <category>github</category>
      <category>javascript</category>
      <category>testing</category>
      <category>tooling</category>
    </item>
    <item>
      <title>I got tired of checking 50 Secretary of State websites, so I built an API</title>
      <dc:creator>Patrick Amey-Jones</dc:creator>
      <pubDate>Thu, 05 Feb 2026 12:48:53 +0000</pubDate>
      <link>https://forem.com/patrick_ameyjones_0379c1/i-got-tired-of-checking-50-secretary-of-state-websites-so-i-built-an-api-8d5</link>
      <guid>https://forem.com/patrick_ameyjones_0379c1/i-got-tired-of-checking-50-secretary-of-state-websites-so-i-built-an-api-8d5</guid>
      <description>&lt;p&gt;Last year I was helping a fintech startup with their vendor onboarding.&lt;br&gt;
Part of the process was verifying that each vendor was actually a registered business in good standing. Sounds simple enough.                &lt;/p&gt;

&lt;p&gt;It wasn't.                                                                 &lt;/p&gt;

&lt;p&gt;To verify a single business, I had to figure out which state they were registered in, find that state's Secretary of State website, navigate their(usually terrible) business search interface, solve a CAPTCHA, find the right entity among similarly-named ones, and screenshot the results for our compliance records.                                                       &lt;/p&gt;

&lt;p&gt;Each lookup took 10-15 minutes. We had hundreds of vendors to verify. I started looking for an API to automate this. There wasn't one. The existing options were either enterprise-only ($50k+ annual contracts) or aggregators with stale data.                                               &lt;/p&gt;

&lt;p&gt;So I built one.                                                            &lt;/p&gt;

&lt;p&gt;What GovLink does                                                       &lt;/p&gt;

&lt;p&gt;You give it a company name and jurisdiction (state), it returns the official registration data: entity status, good standing, formation date,entity type, registered agent, and more.                                   &lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash                                                                    
  curl -X POST "https://govlink.fly.dev/api/v1/verify" \                     
    -H "X-API-Key: your_key" \                                               
    -d "entity_name=Stripe Inc" \                                            
    -d "jurisdiction=DE"                                                     

  Response:                                                                  

  {                                                                          
    "result": {                                                              
      "entity_name": "STRIPE, INC.",                                         
      "file_number": "5765498",                                              
      "status": "Active",                                                    
      "good_standing": true,                                                 
      "formation_date": "2010-07-30",                                        
      "entity_type": "Corporation",                                          
      "agent_name": "CT Corporation"                                         
    }                                                                        
  }                                                                          



Covers all 50 US states. Data is sourced directly from Secretary of State  
offices, not scraped from third-party aggregators.                         

The two-tier pricing thing                                                 

I noticed that a lot of verification workflows involve filtering. You have a list of 100 potential vendors, but you only need full verification on the 10 that pass initial checks.                                              

So I built two endpoints:                                                  

- Pre-check ($0.10) - Just returns status and good standing. Fast, cheap, good for filtering loops.                                                  
- Full verification ($2.50) - Complete entity data, PDF certificate, audit trail.                                                                     

This is especially useful for AI agents. They can do cheap exploration ($0.10 checks in a loop), then only pay for full verification when they've found the right entity.                                                    

MCP support                                                                

I added native https://modelcontextprotocol.io support, so LLMs like Claude can call the API directly during conversations. Point your MCP client at govlink.fly.dev/mcp and the model can verify businesses mid-conversation.  

This felt like the right investment. AI agents are starting to handle real business workflows - procurement, compliance, due diligence. They need reliable data APIs, not web scraping.                                      

Technical notes                                                            

The stack is straightforward: Python/FastAPI, SQLite for customer data, deployed on Fly.io.                                                        

One thing I'm oddly proud of: the customer dashboard is a single 3,200-line Python file with embedded HTML/CSS/JS. No React, no webpack, no node_modules. The entire UI ships as one HTTP response. It has dark mode,  
skeleton loading, keyboard shortcuts, the works.                           

Is this a good idea? Probably not for a team. But for a solo project where I want to iterate fast without context-switching between frontend and backend repos, it works great.                                             

Try it                                                                     

GovLink is live at https://govlink.fly.dev. 10 free lookups to test, then pay-as-you-go.                                                             

If you're dealing with KYB compliance, vendor verification, or building AI agents that need to validate businesses, I'd love to hear what features would be useful.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>api</category>
      <category>python</category>
      <category>fastapi</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
