Bespoke Legacy Symfony App

Bespoke Legacy Symfony App

Nine years, 20 modules, one codebase

I’ve been developing this legacy Symfony app since 2017. In that time I’ve built 20 of the platform’s 23 modules myself, and more than 50 businesses have run on the platform.

That’s the part worth reading twice. Not a project I passed through – a system I’ve owned through nine years of feature work, on a stack that was already ageing when I started.

The legacy Symfony app

This platform is an all-in-one business platform for entrepreneurs and course creators – the kind of system that would otherwise be assembled from a dozen separate subscriptions. Twenty-three modules ship with it today:

Commerce & fulfilment Integrated E-Commerce & Shipping · Advanced Shipping · Bookstore · Affiliate Program · Subscribers

Learning & media Integrated E-Learning · On-Demand Shows · Podcasts · Blogs

Marketing & sales Marketing · Call-to-Action Buttons · Analytics · Contact Management · Surveys & Quizzes

Customer operations Customer Support Tickets · My Zone (customer self-service) · Knowledge Base · Social Community

Business operations Project & Time Billing Manager · Tasks · Website Manager

Each one is a product in its own right. Shipping a checkout is a project. Shipping a checkout, an LMS, a podcast host, a ticketing desk, an affiliate engine and a time-billing system that all share one customer record, one permissions model and one database is a different order of problem – and every new module has to work with the twenty-two that came before it.

The hard part: a codebase older than its own dependencies

The platform runs on PHP 7.2 and Symfony 2.8. Both are long past end-of-life:

ComponentSecurity support ended
Symfony 2.8 LTSNovember 2019
PHP 7.230 November 2020

That single fact shapes every piece of work on the system:

  • Modern libraries won’t install. Current SDKs for payment providers, AI APIs and cloud services require PHP 7.4 or 8.x. On 7.2 you can’t composer require your way out – integrations get built against the raw HTTP API, by hand, with the error handling and retry logic written from scratch.
  • The language is missing its modern safety rails. No typed properties, no union types, no enums, no match, no named arguments, no constructor property promotion. Correctness that a modern codebase gets from the type system has to come from discipline and review instead.
  • Framework patterns are two generations old. Symfony 2.8’s service container, form component, security layer and Twig 1.x templates work differently from anything documented in the last decade. Every Stack Overflow answer and every AI coding assistant will confidently suggest the Symfony 5/6 way of doing it – which doesn’t exist here.
  • It can’t just be shut down for a rebuild. The platform has live tenants running real businesses on it. Their courses, orders, subscriptions and support queues don’t pause for a migration.

How I work on it

I treat the legacy stack as a constraint to engineer around, not an excuse.

  • New features ship into the existing system – no big-bang rewrite, no feature freeze, no “we’ll get to your request after the migration.” Twenty modules went in this way.
  • Modern capability, old runtime. Where the platform needs to talk to services that assume a modern PHP, I build the bridge myself rather than telling the client it’s impossible.
  • Changes are isolated. In a system where 23 modules share one data model, the risk isn’t writing the feature – it’s what the feature touches. Scoping the blast radius is most of the job.
  • Continuity is the real deliverable. On a codebase this old, knowing why a strange decision was made in 2018 is worth more than any framework certification. Nine years in, that context lives in one head, and the client doesn’t have to pay for it to be rediscovered every time a contractor rotates off.

Most developers quietly hope a prospect doesn’t mention their old codebase. If you’re reading this because you have one – a system that earns real money and that nobody wants to touch – that’s the work I actively want.

I’ll tell you honestly whether the right move is to modernise in place, strangle it out module by module, or rebuild, and what each option actually costs, before you commit to one.

Tell us about your project