The practice came to us as someone else's codebase. Nothing was broken, which is the difficult kind of inheritance — everything was simply fragile, and every fragile part was load-bearing. Today the practice publishes its own content, the site is static files on a CDN, and a broken build cannot reach production.
The practice never asked for a redesign, and never got one. Every rebuild was measured against the live site it replaced. What changed is everything a patient doesn't see and an editor feels every day.
The site is HTML on a CDN. Content is pulled once, at build time, by a single typed data layer — not by the browser, on every visit, for every visitor. Interactive pieces load as isolated islands; everything else ships no JavaScript at all.
Wagtail replaced the Django admin panel that had been standing in for one. Fifteen content types, roughly thirty models and 38 raw HTML fields moved to a real authoring surface, with the page tree, previews and permissions that come with it.
Every push builds in CI before production moves. Publishing content triggers the same build. A change that breaks the site fails in the pipeline rather than on the site — which was not true of the shell script we inherited.
We built a small CMS inside the Django admin. That is when we knew we needed a real one.
By mid-2026 we had hand-written draft states, a preview mode, and a registry of pages the editors couldn't reach — all of it custom code we would then own and maintain, badly reimplementing what a CMS gives you on day one. The patches were the argument.
None of these were rewrites for their own sake. Each one had something forcing it: no search visibility, a framework going unmaintained, an end-of-support date, or editors who couldn't publish without us.
Replacing the CMS under a live medical practice is the kind of work that goes wrong quietly. So the cutover was built to be undone: rehearsed on a full copy of production first, and reversible at every step after.
The first full build on the new CMS produced 351 pages with zero errors. That is not the same as the site being right, so we diffed it field by field against the old one and walked it screen by screen.
It found headings being silently stripped out of location pages, fields that had started arriving as objects and rendering as [object Object], formatting collapsed out of older hand-written HTML, and a review widget quietly showing blank cards because the vendor had changed and the new one returns star-ratings with no text. None of those are build errors. All of them are things a patient would have seen.
The same thing happened a rebuild earlier. Our own post-migration audit of the Astro build, written before launch, opened with a homepage hero shipped as a plain blue gradient with its animation missing, a providers page that had lost its location filter, and one page containing the literal words PATIENTS PAGE and nothing else.
Triaged, fixed, then launched. A migration reported to have gone perfectly is usually one nobody checked closely enough — and parity was only auditable because we refused to redesign anything at the same time.
The shape of this work is legacy system modernization; the site it produced is web application development, and the practice it serves is healthcare software.
Send us the repository and the thing that worries you most about it. We will tell you what is fragile, what is urgent, what can wait, and what it costs — before anyone commits to a rebuild.