I decided to rewrite a 200,000-line app from scratch because patching it had stopped making sense.
I published this video in late spring 2025, about 30 days into a rewrite I was doing on evenings and weekends. The app is SnapSuite, my startup's business management tool, and at the time it was north of 200,000 lines of code across two applications. The rewrite wasn't finished. This first part is about why I started it at all.
The business case
SnapSuite started as productivity software for construction and trade workers. It tracks service calls from new to dispatched to completed and ready to invoice. It handles work orders, notes, invoicing, quotes, clients and inventory. When you print or preview a document, it opens Microsoft Word in the background, fills it in and hands you back a PDF.
I'd come to think the app could serve a broader market than construction. That was one reason to re-architect it. The bigger one was speed. A team of developers worked on it, and adding a new feature took too long. When a business can't ship features quickly, it can't chase a bigger market.
This isn't a tutorial, and I'm not trying to sell you the product. It's my own experience of deciding a rewrite was the right call.
A decade of layers
The first version was written around 2012. It grew from a single client build into a much bigger product. We grew, scaled down and grew again, and a lot of developers worked on it over the years.
The front end is Vue.js. The back end is .NET. It started on .NET Framework 3.5, got upgraded to 4.8, moved onto ASP.NET Core when Microsoft changed direction, and then went into Azure Functions, where it sat for a long time.
None of that is wrong on its own. The trouble is that a decade of different technologies and business ideas ends up muddy. The API surface is huge. In the video I scroll through the Postman collection, with print, billing and a long list of other APIs. A new developer can't get productive in a codebase like that without a lot of time.
To be fair to the old app, it works. In the demo, with about 3,500 records in the dashboard, filtering by client or job type is fast.
Proving the size
I didn't want anyone thinking I was exaggerating the line count. So in the video I ran a PowerShell script that walks the project folders and counts the lines in the C# files. The main application came back at about 114,000 lines. The two applications together came to about 214,000. Call it 200,000 and change.
Thirty days of commits
I started a brand-new project for the rewrite in late May. GitHub's Insights view showed the code additions climbing from about 5,000 lines to 10,000, then 15,000, then past 20,000, before tapering off as the new app got bigger.
My goal for that stretch was to build as much of the infrastructure as I could on my own. Once the foundation can scale and the old pieces are replaced, the developers can jump in and focus on features instead of fighting the plumbing.
Jump to
- 0:00 Rewriting 200,000 Lines in 30 Days
- 1:05 What the App Does
- 2:41 A Decade of History and Why Rewrite
- 3:57 The Current Stack and API Sprawl
- 6:09 Proving the Line Count
- 8:21 30 Days of Commits and the Goal
- 10:35 Demo: Creating a Work Order
- 12:47 How the Back End Saves Data
- 14:17 Three Problems with the Async Save Path
- 18:46 Wrap-Up and Part 2
I walk through the app, the line count and the diagram in the full video on my channel: 200,000 lines of code in 30 days, Part 1 on YouTube.
How the old app saves data
In the video I create a work order on test data, and it saves and shows up in the list within about a second. On the surface, nothing's wrong.
Behind the scenes, the save goes to an Azure Function first. The function writes the record to Azure Cosmos DB, which we use as a log we can replay. Then it drops a message on an Azure Service Bus topic and returns success. It doesn't write to the main database itself. A background service picks the message up later and puts the data into the database.
That architecture worked well at the time, and it still works. But it creates three problems I wanted gone.
The missing PO number
A technician out on the road creates a purchase order to buy materials for a job. What they need is the PO number, so they can hand it to the supplier. On the screen where they created it, there's no number yet. The number comes from the database ID, and the record isn't in the database until the background service writes it. It's a delay of seconds, but the user is standing there waiting for it.
The half success
Rarely, a save makes it into the log, but the background service never picks it up. The user got a success message, and they're not wrong, but the data never reached the database. It's a half success. Then they're scratching their heads about why their record isn't on the dashboard. It doesn't happen often, but the last thing you want is customers wondering whether your app worked.
The note that blinks
Add a note, and it shows up at the bottom of the list, disappears and comes back. The browser shows the note right away. Then the app polls the database for new data before the queue has written the note, so the note drops out. A second later the queue catches up and the note reappears. It's not a big deal, but it annoys me, because I know exactly why it happens.
What's next
Those three problems, plus a decade of layers and a huge API surface, were why I decided to rebuild instead of patch. In Part 2 I get into how I rewrote it, including how I used ChatGPT in the process, and what changes in the new design.
If you're weighing a rewrite of your own product, book a strategy call and we can talk it through.