Thirteen years of maintaining a single WordPress theme
RealHomes went on sale in 2013 and has shipped continuously ever since. Almost everything I know about software longevity came from never being allowed to start over.
RealHomes went on sale in 2013. It is still on sale today, still the same product in the same folder with the same text domain, somewhere north of thirty thousand licences later. Almost everything I know about building software that lasts came from a single constraint: I was never allowed to start over.
You cannot deprecate a customer
When a theme is someone's website, an update is not a nice-to-have. It is a Tuesday morning where their property listings either load or they do not. That reframes every technical decision. A refactor that would take a week and break child themes is not a refactor, it is an outage with a changelog attached.
So the question stopped being "what is the best way to build this?" and became "what is the best way to build this that also lets the person who bought version 1.2 keep working?" Those are very different questions, and only one of them shows up in tutorials.
Three designs, one codebase
RealHomes ships Classic, Modern and Ultra. They look like three different themes and share almost all of their logic. That only works because the data layer never knew about the design layer. Property fields, search, and the dashboard are the product; the templates are opinions about the product.
Every time we blurred that line to ship something faster, we paid for it two versions later. Every time we held the line, we got a new design variation for a fraction of the cost.
The templates are opinions. The data model is the product. Keep them apart and you can change your mind later.
What actually breaks over a decade
It is never the thing you worry about. In thirteen years the genuinely painful migrations were:
- PHP version bumps. Not the syntax, but the quiet behavioural changes. Implicit conversions that used to pass silently and now throw.
- jQuery moving underneath us. A decade of accumulated front-end assumptions, all needing to be true at the same time.
- The block editor. Not because it was bad, but because "supporting it" meant something different every year for four years.
- Third-party plugins we never chose. Customers install what they install. Our compatibility surface is not our dependency list.
The boring parts that saved us
Versioned, idempotent migrations. A deprecation policy with real dates rather than good intentions. Filters and actions on anything a customer might reasonably want to change, so they extend instead of edit, because a customer who edits core files is a support ticket scheduled for the next release.
And a release checklist boring enough that a tired person can follow it correctly. That last one is not a joke. Most bad releases I have seen were shipped by someone competent who was in a hurry.
Would I do it again
Yes, though I would write the deprecation policy in year one instead of year four. The compounding value of a product that people can rely on for a decade is enormous, and it is almost entirely built from decisions that felt over-cautious at the time.