Let’s start with a universal truth: every developer, when encountering a piece of existing code, immediately thinks, “Who wrote this trash?” And if the answer is “me,” the follow-up is “Well, golly-damn, how I’ve grown since then.” It’s instinct. Like salmon swimming upstream or clients adding scope.

But here’s the thing: if the software is running today, in production, doing an actual job… it’s legacy. It might not feel like it. It might still be using a trendy JavaScript framework with a name like a craft beer. But if it exists, it’s already aging.

Legacy Means It Works

“Legacy software” has become shorthand for “bad” or “outdated,” but that’s just often dev-speak for “I didn’t write this, and I don’t want to understand it.” In reality, legacy means functioning. It’s the survivor of a thousand sprints and stakeholder whims. If it’s still running, it beat the odds.

Now, don’t get me wrong. Most systems that are dragged to MY door to look at are not actually functioning. Someone calls my company because their software was drooling on the floor and causing embarrassment. The shit that I’ve seen would blow, your, mind. But that’s not what this blog is about.

We’re talking about software out there, living in the wild! It takes time to build something that doesn’t fall over every time a user sneezes. It takes even longer to secure it, document it, get it to interoperate with ten other weird systems, and stop everyone from rage-deleting it. So by the time any piece of software is stable, it’s already old. It’s already legacy.

Not Built, But Grown

Most production code didn’t emerge from the forehead of Zeus. It was assembled by overcaffeinated teams juggling client demands, budget changes, and the immortal words: “We just need this to go live next week.” Some team (who all argue about A24 movies) wrote it to work, not to impress some future prospective employer reading the commits on GitHub.

And even the “perfect” systems? The ones designed by IBM consultants with flowcharts written in blood? Those are more legacy. They’ve been running longer than some of your engineers have been alive. The problem isn’t that they’re bad. The problem is that they’re good enough to keep running, and nobody alive today knows how to update them without summoning Cthulhu via an old terminal. One of the great pleasures of my career was working with an 82-year-old Senior Software Engineer to refactor a giant risk management system running on IBM AS400. That thing was unhackable, had ran for 50 years straight, and when it crashed no one remembered how it worked.

Rewrite and Regret

Every developer has had the impulse to scrap an existing codebase and rewrite it from scratch. That’s the dream: clean slates, elegant abstractions, no weird edge cases left behind by Steve in Accounting who once “fixed” a bug with a semicolon and a prayer.

But rewriting software just means writing new legacy. You’re trading one set of sins for another, and now you own the sin. Worse, it probably won’t even ship with all the features the old version had, because, well… you forgot how much of that was important.

There Is A Right Way, Of Course…

That’s to slowly but surely rewrite independent modules, send out press releases about your new fancy features, ride the wave of glorious press coverage to your next PE or VC round, and replace the dinosaur bit by bit. But that’s not what this blog is about either.

AI: Now With More Legacy

And now there’s AI-generated code. These systems can crank out tens of thousands of lines in a week, and some of it looks legit… at first glance. But under the hood, AT LEAST FOR NOW, it’s often not great.

The speed of generation doesn’t mean quality, it just means you’ll reach the legacy stage faster. “Move fast and break things” is now “Move fast and drown in your own tech debt.”

Embrace the Patchwork

Software is patchwork. It has scars. It evolves, like a Pokémon that starts off as a fish and eventually becomes a bear or something. It carries around evolutionary leftovers that don’t make sense anymore but can’t be removed because five other systems depend on them. And that’s okay.

The job isn’t to hate it. The job is to shepherd it. To improve it where you can, reinforce the parts that work, and refactor the parts that need a little love.

Set Expectations, Stop Whining

So let’s stop acting like “legacy” is a four-letter word. Let’s teach our stakeholders, our clients, and ourselves that software is a living, breathing mess, and that’s fine. I always use the metaphor that software is like a garden. It requires constant care, weeding, and occasionally cutting bits out and putting in new soil. Feel free to steal that.

Every codebase is a conversation across time. Every app is a reflection of the best we could do back then. The question isn’t “Is this perfect?” It’s “Does this work well enough to keep going, and how can we make it better without starting over?”

Unless it was built by Sourcetoad. Then, of course, it’s perfect.

(Except when it’s not. We refactor it too.)

Previous ArticleNext Article
I help companies turn their technical ideas into reality.

CEO @Sourcetoad and @OnDeck

Founder of Thankscrate and Data and Sons

Author of Herding Cats and Coders

Fan of judo, squash, whiskey, aggressive inline, and temperamental British sports cars.

Leave a Reply

The Internet Doesn’t Have Enough Love In It (And How We Can Fix It Easily)

I’ve been thinking about all the wrong things when it comes to AI writing code.

Everyone else seems to be too. Job displacement. Security vulnerabilities. The ten-times-faster developer who now bills the same and delivers four times as much. These are real conversations worth having, just not the one I want to have right now.

The one I want to have is about teaching a six-year-old multiplication.

Here’s what I mean. Imagine you’ve been sitting with your kid every night for two weeks trying to explain multiplication. You’ve tried drawing rows of dots. You’ve tried songs (don’t judge me). You’ve tried the “just think of it as groups of things” approach that works for literally every other math concept but, mysteriously, not for your kid. Then one night, something clicks. You found the explanation, YOUR explanation, the one that worked for your actual kid with your actual kid’s brain, and it finally, beautifully, clicks.

Now imagine you could spend a Saturday morning turning that into a small web app. Not a startup. Not a SaaS platform. No login. No backend. No one’s going to hack it (there’s nothing to hack). Just a little thing that walks through multiplication the exact way you figured out it works, step by step, the way you’d explain it. You send it to the WhatsApp group for your kid’s class. Some of those other parents, also quietly losing their minds over multiplication, try it. And it helps.

You just made the world a tiny bit better. That’s it. That’s the whole thing.

Claude Code exists now, and a handful of other tools like it, and the reason I think this matters isn’t productivity. It’s access. The barrier between “I have an idea for something that could help people” and “I have a thing that helps people” used to require knowing how to code, or hiring someone who does, or talking a developer friend into your project over enough beers that their guilt exceeded their better judgment. Now it’s a Saturday morning and a good description of what you want to build.

The internet already has beautiful things in it that were built out of love. Free coding education for kids. Open-source video editors. Someone’s incredibly detailed home-brewing app with no monetization plan whatsoever. Artists making interactive experiences because they wanted to see if they could. These things exist because someone cared more about making the thing than making money from the thing. I think that ratio is about to shift dramatically in favor of the people who just want to make something good.

I’m not saying we should all stop paying for Salesforce (we should probably keep paying for Salesforce, there’s a reason that thing costs what it costs). I’m saying the category of software that was previously not worth building because it wasn’t commercial enough to justify the cost, that category just got a lot more interesting.

What’s in that category? Things like:

  • An app that helps beginning judo students understand the concepts behind a throw, not just the mechanics, because judo is where I learned confidence and discipline and I want other kids to find that
  • A private family memory vault (not Instagram, not Facebook, not anything with an algorithm deciding what matters), just a place where the people who love my son can send photos and stories somewhere safe, for him to open when he’s older (Maybe I’ll turn this into something?)
  • A system that reminds companies to send their employees gifts on the days that actually matter to them, because I know from running a company that it fills the cup of the person giving just as much as the person receiving (Thankscrate, if you’re curious, and yes, that one is turning into something real, but that is genuinely not why I built it)

None of those were commercial ideas first. They were just things I cared about.

I think the most interesting software that gets built in the next few years won’t come from developers moving faster. It’ll come from people who previously had no path from “I care about this” to “I built something about this,” and now they do. Parents. Coaches. Teachers. The person in your office who could explain that one complicated process better than anyone and has always secretly wanted to turn it into something.

The stakes are low. The bar to launch is low. The cost is low. The only thing required is that you actually give a damn about what you’re building.

So… What do you give a damn about?

Go build it. I still sometimes have to count on my fingers, but I’m told the app helps.