Skip to content

Lesson 1 of 17 · Setting the Stage

Introduction - Why Most Codebases Rot

Beginner•
lesson•
August 13, 2026•
~6 min read

The pattern you've probably seen

You join a project and the first month feels good. You ship features fast, and the codebase is small enough to hold in your head. You and the team make jokes about how nice it is to work on something that "isn't legacy yet."

Two years later, you don't touch a file unless you have to. A two-line change takes a day because nobody is sure what else it breaks. The tests are slow, flaky, or commented out. New hires ask questions that nobody can answer. Someone proposes a rewrite. Someone else says the rewrite will end up in the same place, and they're probably right.

I've watched this happen at startups, at scale-ups, and inside enterprises with hundreds of engineers.

That's the thing that bothers me. If it were one bad team or one bad framework, we could blame the team or switch the framework. That's not the case. The pattern is too consistent for that.

It's not the framework's fault

When a project goes bad, we usually blame something external. "Laravel doesn't scale." "Symfony is too heavy." "The previous team didn't know what they were doing." "We picked the wrong ORM."

Sometimes those things are true but they're rarely the actual cause.

I've seen not-so-well architected projects in native PHP and Laravel that have lasted many years in production somehow, and they are still successful today. But the maintenance hurdle is real.

Blaming the framework is comforting because it implies a clean fix: change the tool, change the result. It almost never works that way. Every rewrite I've watched take a bad project into a new one from scratch has ended up as a new bad project in the same framework.

What actually causes rot

Codebases rot because of how we think about code, not just what we write into the editor or ask an AI agent to write for us. A few forces show up over and over:

  • Decisions made without context. Someone reads a blog post about hexagonal architecture and applies it to a CRUD admin panel that needs to ship with a tight deadline.

  • Code optimized for writing instead of reading. The author understood it when they wrote it, but once someone else has to touch it, nobody does, including them.

  • Abstractions added at the wrong time. Either too early, when nobody knows the shape of the problem yet, or too late, after the duplication has already calcified into ten slightly different versions of the same thing.

  • Business logic scattered across the framework. Rules that should live together end up split between a controller, a model, an event listener, a queue job, and a Blade template. Changing one means hunting through five.

  • Naming that describes mechanics instead of intent. For example: UserService, OrderManager, DataHandler, words that tell you nothing about what the code is actually for.

  • One use case being reused for multiple different unrelated use cases. An API endpoint that changes some kind of data with a bunch of if statements trying to determine which use case the code will follow.

I'm naming these now so you have something to hold onto. The rest of the course is the explanation.

Why most resources don't help with this

Tutorials, books, and bootcamps teach you syntax, patterns, and how to ship a feature. All of that is useful, but none of it prepares you for what a codebase looks like at year three or year five.

The hard part of software is not learning a framework, it's making decisions today that the team you haven't hired yet won't curse you for years from now. That part is barely taught anywhere. You pick it up by working on long-lived projects, watching them go wrong, and slowly forming opinions about why.

This course is a shortcut for that. Not a complete one, because you still need scars to really understand some of this, but a head start. It will teach you why good software design is important.

What this course is

This is the course I wish I had when I started my career more than a decade ago.

It's about the mindset that comes before any pattern, framework, or rule, the "why" that has to exist before the "how" is worth anything. Most of it is theory, there's some code, but the code is there to make a point, not to copy.

You will leave this course with:

  • A vocabulary for talking about why code rots, so you can name what you're seeing instead of just feeling that something is off.

  • A set of mental models for thinking about trade-offs in real projects, where every decision has a cost.

  • A sense of which problems are worth solving early, which are worth solving later, and which are not worth solving at all.

That's it, no silver bullets and no "ten rules to write clean code." Those don't exist, and anyone selling them is selling something else.

What this course isn't

It isn't language or framework-specific: the examples use PHP, and everything here applies just as well to Python, Ruby, Go, TypeScript, or any other language where teams build long-lived software. It also isn't for absolute beginners. If you're still learning what a class is, this course won't help you yet. Come back after you've built a few real projects and felt them get harder to change.

Who this is for

This is for the developer or software engineer who has built things and felt them turn against them, the one who has opened a file they wrote a year ago and didn't recognize a line of it. The one who has watched a clean project become a mess and wondered when, exactly, it happened.

If that's you, the rest of the course will make sense. If it isn't yet, save this for later.

How to read it

Read the lessons in order. Each one assumes the ones before it. Skipping ahead works for reference material but this is not it.

Some lessons will feel obvious, read them anyway. The obvious ideas are the ones we forget under deadline pressure, and forgetting them is what causes most of the damage.

Some lessons will feel uncomfortable. I did that on purpose: if nothing in this course pushes against the way you currently work, I haven't done my job.

Also, don't forget to try experimenting with some of these ideas on your own to see how you like them and see if they will make sense in the projects you are working on.

The one thing to remember

Codebases rot because decisions that were right for the team and the product at one point in time never get revisited once the team and the product change.

Those six causes are what that neglect looks like in practice. The rest of this course is about catching those decisions before they calcify, not years after, when nobody remembers why they were made.

Course Content

Introduction - Why Most Codebases Rot
Lesson
Sign in to track your progress
It All Depends on the Context You Are In
Lesson
The Cost of Change Curve
Lesson
Reading Code vs Writing Code
Lesson
Coupling and Cohesion
Lesson
Accidental vs Essential Complexity
Lesson
Under-Engineering vs Over-Engineering
Lesson
Premature Abstraction
Lesson
Technical Debt and the Boy Scout Rule
Lesson
Framework Coupling vs Framework Decoupling
Lesson
Thinking Data vs Thinking Business Processes
Lesson
Naming Things by Intent
Lesson
Planning Before You Code
Lesson
Strategic vs Tactical Programming
Lesson
Model-View-Controller - The Baseline We All Know
Lesson
Reading a Codebase You Didn't Write
Lesson
Recording the Why
Lesson