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

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.

About Dwain

Dwain Browne

I'm Dwain Browne, Founder of LeadScore AI and SnapSuite. I'm a Toronto-based software architect with 25+ years across software, sales, operations and entrepreneurship. SnapSuite helps contractors and trades teams get paid faster, and LeadScore AI shows you which leads deserve your next call. I also run Vibe Code to Profit, a community helping people build software with AI.

YouTube · LinkedIn · Book a call