Refactoring as a Solo SaaS Founder

Mitch Edwards
4 min readJan 26, 2024

--

When I first began my journey as a solo SaaS founder and developer, I was wrong about… most things.

  • If you build good code, the customers will come! Wrong — you should probably learn marketing.
  • Front-end design doesn’t matter if you’re marketing to nerds! Maybe, but your front-end design sucks so bad that CLI nerds don’t even want to use it.
  • Microservice architectures are more scalable and easier to extend and change! Probably wrong, but definitely wrong if you suck at microservice architecture design.

One of the biggest things I was wrong about early on, though, is my approach toward refactoring. My thought process was that I’m not going to be working with a team (at least any time soon) so what’s the point in refactoring my code? After all, if I write it, it’s gotta be readable to me!

Oof.

Anyone who has written even reasonably complex NextJS/React code with Tailwind, authentication and the rest of it knows this isn’t true. Code turns to spaghetti, inexplicable ghost functions appear from late nights spent coding far past the point that the brain is able to write legible code and .tsx files appear out of thin air as if willed there by a higher (or lower) power. Tailwind classnames with screen sizes all out of order, flex boxes and grids somehow ending up in the same class, all manner of horrific anarchy litters your codebase, with nothing more than a few TODO comments to “document” the insanity.

In short, refactoring is just as important for the solo dev as it is for a team. I’d argue it’s even more important.

How I Refactor

I like to do refactoring sprints. What this usually looks like is I finish a new feature for GrabbrApp and I push it to prod, wait a bit to see what breaks, and when I fix all (well, some) of the brokenness, I will do a fairly short refactoring sprint.

Usually, I’ll start my focus on the big pages for my web application, as well as the code I just pushed to production. This means a heavy emphasis on extracting pieces out for reusable components, cleaning up ambiguous or duplicate code, cleaning up duplicate Tailwind class names, etc. After I’ve done this, I’ll take a look at the back-end. What routes can be cleaned up? Am I handling asynchronous function calls well? Are there any dead routes or components in my front end or back end?

Most of my refactoring is focused on a net reduction of code, or at least an efficient organizing of my code. This gets into the core reason why I recommend frequent refactoring.

The Why: Less Code ~= Less Stress

As a solo developer, and especially as a solo founder, you get to wear a lot of hats. Front end and back end development, CI/CD devops, testing, and plenty of other technical focuses competing over time with marketing, sales, administration, strategic planning and more. Your time is precious and in short supply, and that means your code base has to be efficient and succinct.

The less time you spend searching for problems or wrangling spaghetti code in an attempt to add a feature or remove a bug, the more time you can be writing marketing content, hopping on a sales call or working on the next big feature. The less code you have to deal with, the more code you can deal with.

Secondary Focus: Eliminating Complexity

You’ll frequently find that your initial solution to a hard problem was not necessarily the best one. Frequently, you’ll create a bit of a mess in creating an overly complex solution to a problem when you really didn’t need to, but you just need to get that solution or feature out quickly so you don’t make the time to fix it up or make it more efficient.

Ideally, you avoid this tradeoff completely and write your code the best way the first time, but we all know that’s not going to happen. Spending some time during your refactoring sessions taking a look under the hood at how you’re fetching and processing data to see if you can simplify it can help a lot. I also spend a good bit of my time during refactoring sessions writing code documentation, usually in the form of inline comments, so that the next time I’m refactoring, fixing a bug or working on a feature, I can navigate the code base easier.

Simpler systems generally work better, though the definition of simple versus complex is and always has been heavily debated. Using refactoring sessions, or even refactoring sprints, to eliminate unnecessary complexity will pay off dividends in the long run.

Don’t sleep on refactoring, even as a solo dev

I’m not trying to proselytize. I’m not even really trying to tell you some deep, dark and unknown secret here. Obviously refactoring is a well-known, tride-and-true habit for lots of developers, so if you’re part of a highly-skilled, high-speed, low-drag 10x dev team, this blog isn’t for you.

The person this is meant to convince is me a year or two ago, when I first started seriously building out GrabbrApp. I have lots of messages I’d like to deliver to me before seriously building GrabbrApp:

  • Do not choose NextJS.
  • Do not do a microservice Golang architecture.
  • Do not get fancy.
  • Refactor your code, studiously and often.

I’d have saved myself a lot of prod bugs, a lot of time, a lot of sleepless nights if I’d refactored my code more often. Don’t be like me, or, if you must, make sure you learn the same lessons I did.

--

--

Mitch Edwards

Cyber Threat Intelligence Analyst, primarily focused on Chinese cyber crime and APT activity. GitHub: https://github.com/vikingSec