Open any of the app's old screens and you're looking at tools from its early days: around six hundred templates, and a styling kit that hasn't kept up. The app is the CRM a group of exercise clinics uses to keep track of everyone who has shown interest, and staff work in it all day. Rewriting it all at once would have meant months with nothing to show and one risky switch-over day. So the new design runs alongside the old one.
Each person chooses which version they see, and can switch back from any page. A page that has been redone keeps both versions side by side, and the app picks one for each request based on that choice. A page that hasn't been redone yet shows the new frame with a link to open the old version, so nobody gets stuck. If a new page has a problem, switching back is one click and nothing is lost.
It started behind a switch only a few staff could see. Once the pages they used every day were done, it opened to everyone, and each person still opts in when they're ready.
Plain pages, with islands
Most of the new pages are still plain pages built on the server, from a small kit of shared parts like tables, filters and forms. That keeps the rules about who can see what in one place. Another toolkit, React, is only used for the pieces that need it, dropped into an otherwise normal page: a canvas for drawing follow-up journeys, drag-to-reorder lists, a text editor, a search box that answers as you type, and a chat that answers questions about the data, which has its own post. Engineers call these islands. Building the whole thing as one big React app would have meant writing every permission rule a second time.
I build a lot of this alongside a coding agent, an AI that writes code, so the docs are written for it to follow. Because each page follows the same recipe, it can redo one from a written checklist, and a test proves both versions still work before it's merged. Automated checks run only on the files that changed. Old security warnings are recorded as a starting point, so new code has to be clean without first fixing years of old code.
Where it stands
Over 250 pages have new versions so far. Each new one follows the same recipe: a page redone from the checklist, and a test that proves both versions still work before it's merged.
Rails 8.1, ViewComponent, React 19, Vite, Tailwind.