Journal → Studio → What I've Learned About Building Software After 20 Years of Doing It
Studio · Jun 7, 2026 · 7 min read

What I've Learned About Building Software After 20 Years of Doing It

I've been writing code and shipping software since I was a teenager. Not at a FAANG company, not in a computer science PhD programme — just building things on the internet, one after another, for over two decades. Some of those things made money. Some of them were terrible. All of them taught me something about the craft of making software.

These aren't best practices from a textbook. They're patterns I noticed by getting things wrong repeatedly and eventually getting them less wrong.

Shipping beats everything

The graveyard of unfinished software projects is enormous, and I've contributed to it generously. Half-built apps sitting in repos, prototypes that were going to be "ready next week" for six months, architectures that were so carefully planned they never produced a working product.

The single biggest differentiator between developers who build things people use and developers who don't isn't talent. It's the willingness to ship something imperfect.

Version one of anything is embarrassing. That's fine. It's supposed to be. The goal of version one isn't to impress anyone — it's to exist. You can't improve something that doesn't exist. You can't get feedback on something nobody can use. You can't learn what users actually need from a product that's still in your head.

Ship it. Fix it after. This sounds obvious written down, but in practice it goes against every instinct a careful developer has.

The technology matters less than you think

I've built products in PHP, Python, JavaScript, Swift, and a handful of other languages. I've used frameworks that were trendy and frameworks that were ancient. The products that succeeded and the products that failed had no correlation whatsoever with the technology stack underneath them.

What mattered was whether the product solved a problem. That's it. Nobody has ever stopped using software because it was written in the wrong language. Plenty of people have stopped using software because it was slow, confusing, or didn't do what they needed.

The tech stack debates that dominate developer communities — React vs. Vue, PostgreSQL vs. MongoDB, monolith vs. microservices — are interesting intellectual exercises. They're also almost completely irrelevant to whether your software succeeds. Pick something you know, build the thing, and move on. You can always rewrite it later if the technology becomes a genuine bottleneck, which it almost never does.

Complexity is the enemy

Every piece of software starts simple. A clear idea, a clean codebase, a few features that work well. Then it grows. Features get added. Edge cases get handled. Integrations get bolted on. The configuration file that started at 10 lines is now 400. The database schema that was three tables is now thirty.

At some point — and the timing is different for every project — the complexity crosses a threshold where the software starts working against you instead of for you. Changes take longer. Bugs appear in places you didn't touch. New developers look at the codebase and quietly update their LinkedIn profiles.

I don't think you can prevent this entirely. But you can delay it significantly by treating every addition as a cost, not just a benefit. Every feature, every abstraction, every "what if we also..." has a maintenance price tag that extends for the lifetime of the project. Most of the time, the price isn't worth it.

The best code I've written isn't clever. It's obvious. Anyone can read it, anyone can modify it, and it does exactly what it needs to do without trying to handle seventeen hypothetical scenarios that never materialise.

Solve your own problems

The most successful software I've built solved problems I personally had. The least successful was software I built because I thought other people might want it, based on market research and competitor analysis and all the things you're supposed to do.

When you solve your own problem, you have an unfair advantage: you're your own first user. You know the pain point intimately. You know which features matter and which are noise. You can test the product just by using it for a day.

When you build for an imagined user based on personas and surveys, you're guessing. Educated guessing, maybe, but guessing. And you don't find out whether you guessed right until months later when the usage data comes in.

This isn't universal advice. Plenty of great software was built by people who didn't personally have the problem. But if you're solo or on a small team, starting with your own pain is the highest-probability path to something useful.

Maintenance is the real job

Writing the initial code is maybe 20% of the work. The other 80% is keeping it running. Updating dependencies. Fixing bugs that only appear in production. Handling the edge case where a user pastes emoji into a field that expects ASCII. Migrating data when you change the schema. Renewing certificates. Responding to monitoring alerts at inconvenient hours.

Nobody romanticises this part. It's not the subject of conference talks or blog posts. But it's where software lives or dies. I've seen beautifully engineered products die because the developer got bored of maintaining them. I've seen ugly, cobbled-together products thrive because someone kept showing up and fixing things.

If you're not willing to maintain something for years, think carefully before building it. Launching is an event. Maintenance is a commitment.

The tools changed, the work didn't

I started building software with a text editor, an FTP client, and a prayer. Now I have AI assistants, CI/CD pipelines, cloud infrastructure, containerisation, automated testing, and monitoring dashboards. The tools are incomparably better.

The work is the same. Understand the problem. Figure out a solution. Build it. Ship it. Listen to users. Improve it. Repeat.

The developers who thrive long-term are the ones who stay focused on that loop regardless of what tools are available. The tools accelerate the loop. They don't replace it.

Keep going

If you're early in your software development journey, the most valuable thing I can tell you is: keep building. Not one project for five years — although that has its own merits — but many things, frequently. Each project teaches you something the previous one didn't. Your taste gets better. Your judgment about what to build and what to skip gets sharper. Your tolerance for imperfection in version one increases, which paradoxically leads to better products.

Twenty years in, I still feel like I'm getting better at this. That's either encouraging or a sign that I was very bad at it for a long time. Probably both.