// Insights

Cutting a Legacy Monolith's Bundle Size by 90%: A Migration Approach

Moving from a monolithic frontend to a modular, component-driven architecture — and the schema work that made the performance gain stick.

  • Modernization
  • Performance
  • Next.js

When the bundle becomes the roadmap's ceiling

A monolith that made sense at launch eventually becomes the reason every change takes longer than it should. One symptom is architectural — a single deploy for the whole system, a database schema no one wants to touch. Another is more measurable: the JavaScript bundle keeps growing, because every new feature adds to one shared frontend module with no boundary stopping it, and nothing in the system forces anyone to notice until page load times are visibly bad.

Our engineers have migrated legacy monolithic frontend modules to a modular, component-driven Next.js/React architecture, reducing bundle size by ~90%. That number is the outcome; the approach underneath it is what makes it repeatable.

Migrating incrementally, not as a big-bang rewrite

The instinct with a slow, tangled monolith is to freeze feature work and rewrite it from scratch. That's usually the wrong call — a big-bang rewrite means the system is unshippable for the duration of the migration, and the rewritten version inherits the same risk of drifting from what the business actually needs by the time it ships.

The alternative is migrating module by module: pick a bounded piece of the monolith, extract it into a component-driven structure with its own explicit boundaries, and ship it alongside the parts that haven't moved yet. Each migrated module stops contributing to the shared bundle and starts loading only what it actually needs. The system stays in production and shippable throughout, and the bundle-size reduction compounds as more modules move.

Performance recovery isn't just the frontend

A smaller JavaScript bundle fixes load time. It doesn't fix a database that's still returning results slowly under the same query patterns that existed before the migration. Paired with MySQL schema optimization work, this kind of frontend migration can be combined with a ~90% response-time improvement on the database side — schema and indexing changes aimed at the queries the application actually runs, not a generic optimization pass.

Treated separately, bundle size and response time are two different engineering problems with two different fixes. Treated together, as a combined performance-recovery project, they turn "the app feels slow" from a vague complaint into two measurable before-and-after numbers.

If you're facing the same problem

Start with an audit, not a rewrite plan: what's actually in the bundle, what's actually slow in the database, and which parts of the monolith are safe to extract first without breaking the parts that stay. Migrate the highest-value, lowest-risk module first to prove the pattern, then keep the system shippable at every step after that. The bundle-size number and the response-time number are both things you should be able to measure before you start and after each migrated module — if you can't measure it, you don't know if the migration is working.

Read more about our approach on the legacy modernization service page.