The brief

Our client — a mid-stage healthcare SaaS serving small clinics — had built their original product in a frenzy of early-stage execution. Five years in, the codebase had grown into a tangle of feature flags, dead code, and inconsistent UX patterns. New customers churned during the trial period because the onboarding felt unfinished. The internal team spent most of their week fighting fires instead of shipping new features.

They asked us a clear question: can we rebuild this in twelve months without losing customers?

What we found

The technical audit surfaced three structural problems. First, the data model had drifted — three different tables represented "patient" depending on which feature wrote to them, and reconciling them was a daily ops headache. Second, the frontend was a single 4MB JavaScript bundle that took 8+ seconds to interactive on a mid-range laptop. Third, the design system existed only as a Sketch file last updated in 2022.

None of these would be fixed by adding more features. The product needed a structural rebuild, not a polish.

Our approach

We proposed a four-phase rebuild over twelve months:

  1. Phase 1 — design system and core flows. Three months of design work, building a token-driven system and redesigning the highest-traffic flows (login, patient search, patient detail).
  2. Phase 2 — backend consolidation. Migrate to a unified data model with strict tenant isolation, behind feature flags so the old and new could coexist.
  3. Phase 3 — frontend rebuild. Rebuild the frontend on Next.js with server components, route-level code splitting, and a proper design system implementation.
  4. Phase 4 — migration and sunset. Migrate customers tenant-by-tenant, monitor closely, sunset the old system.

The hard part

The hard part wasn't the rebuild — it was running two systems in parallel for six months while customers migrated. We invested heavily in observability: every new-system request was tagged so we could compare error rates, latency, and conversion against the old system in real time.

The discipline that mattered most: we did not add a single new feature during the rebuild. The product owner had to defend that decision repeatedly. It saved the project.

The outcome

  • Page-load time dropped from 8.2s to 1.9s (Largest Contentful Paint, median session).
  • Trial-to-paid conversion increased 22% in the first quarter post-rebuild.
  • Internal feature velocity tripled — measured by stories closed per sprint after the migration completed.
  • Customer support tickets related to "the system is confusing" dropped 60%.

What we'd do differently

The migration phase took two months longer than we estimated. We underestimated how much of the original system's behaviour was undocumented and only known to long-time customers. If we did it again, we'd do a more thorough pre-migration audit with the customer success team to surface those expectations earlier.