Rebuilding a Legacy Frontend in React Without a Risky Redesign
Stack
- React
- PHP
- jQuery
On this page
Key results
- PHP/jQuery frontend
- Retired
- Rebuild time
- ~4–5 months
- React component system
- Shared
- User experience
- Unchanged
Problem
Better Coaching is a multi-tenant SaaS platform that football clubs and academies use to manage coaching, players and training content.
The inherited frontend was a server-rendered PHP application with heavy use of jQuery and AJAX-loaded HTML fragments. UI behavior was spread across:
- PHP templates;
- jQuery handlers;
- AJAX-loaded fragments;
- inline event handlers;
- duplicated interface logic.
With no component model for reusing common patterns, the result was duplicated code, inconsistent behavior between screens, more regressions and slower feature work. The issue wasn’t the age of the technology so much as a codebase that had become tightly coupled and expensive to change safely.
A full visual redesign had been discussed as a possible later stage. Combining it with a technical rewrite would have greatly increased scope and risk, so the priority was clear: modernize the frontend architecture first, keep the product stable, and leave a larger redesign for later.
My role
I was the team lead on the rebuild. I set the direction to modernize the frontend separately from any redesign, and led the team through rebuilding the application in React and introducing a shared component system.
Much of the job was holding the line on scope, keeping the migration about the technical foundation even where improving the UI along the way was tempting.
Technical approach
Building the React app alongside the old frontend
Instead of gradually mixing React components into the PHP pages, we built a separate React application and recreated existing functionality in it while the original stayed live. The team could rebuild screens and workflows without changing the production interface under existing users, and the migration had a clear boundary:
- Old PHP/jQuery frontend
- New React frontend
The product was never left permanently split between two frontend architectures.
Keeping the existing API
The backend modernization was a separate problem, and the frontend didn’t wait for it. The React application first talked to the existing PHP API, so only one architectural layer changed at a time and the backend could be modernized independently later.
Reusable UI architecture
The legacy frontend had accumulated UI patterns without a consistent component system. We introduced reusable components and shared patterns for:
- buttons;
- form controls;
- typography;
- colors;
- spacing;
- layouts;
- common interactions.
Screens increasingly built on shared building blocks instead of re-implementing similar logic each time.
Recreating existing behavior
Moving from server-rendered fragments and jQuery to React wasn’t a visual conversion. It meant rethinking:
- application state;
- component boundaries;
- data fetching;
- form behavior;
- UI updates;
- reusable functionality.
The result had to look and behave the way customers expected while the internals changed substantially, without carrying over the problems that made the old frontend hard to maintain.
Decisions & trade-offs
Technology first, redesign later
It would have been tempting to change the visual design, navigation, interaction patterns and application structure along with the technology. But with all of that changing at once, it would be hard to tell whether a problem came from the new implementation or from changes to the product. The rule we worked to:
Change the technology first, not the product customers already know.
What not to change
Rebuilding screens constantly exposed things that could be cleaner, simpler or more consistent. But every redesign choice added a variable. If a user struggled with a new screen, was it:
- a bug in the React implementation?
- a changed workflow?
- a redesigned interaction?
- a behavior missing from the old system?
So we accepted a trade-off: some existing UX limitations stayed for now. The goal wasn’t the final visual version of Better Coaching, but a stable foundation that makes those improvements easier to build later.
Not changing frontend, backend and UX at once
Keeping the PHP API during the rebuild applied the same principle to the backend. Instead of a new frontend, a new backend and a new UX at the same time, the first target was a new frontend on the existing backend with a familiar UX. That cut the number of moving parts and kept the new application easy to compare against known behavior.
Results
Legacy frontend retired
After about four to five months, the React application had replaced the PHP/jQuery frontend entirely, and the legacy frontend was retired rather than maintained alongside it.
Faster feature work
Reusable components, consistent patterns and clearer separation of concerns reduced the code each new feature needs. Feature development became noticeably easier and faster than in the inherited frontend.
Consistent UI changes
Common styling and behavior now live in shared components, so product-wide changes are made once instead of across separate templates and scripts.
Focused modernization risk
Because the redesign was postponed, testing was more straightforward. The new application could be compared directly against familiar existing behavior.
A foundation for a future redesign
The rebuild was never meant to be the final visual version of the product. Future UX and design work can now build on React components instead of the old PHP/jQuery structure, with technical debt and product redesign handled as two separate problems rather than one.