Engineering

React and Vite migration without a rewrite

A practical approach to moving older React or Create React App frontends toward Vite while protecting production delivery.

A React-to-Vite migration goes wrong the moment it turns into a redesign. The safest version replaces the build and development foundation underneath an application while keeping its visible behavior exactly the same. Faster local builds are worth a lot, but only if production stays boring throughout.

When the problem appears

The frontend usually announces it is overdue. The dev server takes a long time to start and reload. The build tool is on an old, slow path such as a legacy Webpack or Create React App setup that no longer receives much attention. Upgrading a single dependency cascades into config changes nobody wants to own. New hires lose a day to environment setup. The application still works, but every interaction with the build makes the team slower, and that tax compounds.

Common failure modes

Bundling migration with redesign. Changing the build and refactoring components at the same time makes regressions impossible to attribute. When something breaks, you cannot tell whether it was the new build or the new code.

Underestimating build assumptions. Environment variables, asset paths, test tooling, TypeScript configuration, proxy behavior, deployment target and CI commands are where migration surprises actually live. They are easy to forget precisely because they are implicit.

Skipping a compatibility pass. Routing, forms, authentication flows, admin screens, analytics, feature flags and static assets often behave subtly differently after a build change. Without checking them deliberately, the differences ship to users.

Trusting local success. A fast local build that has not been exercised through the real deployment path proves little. The interesting failures appear in CI and in production previews.

A controlled approach

List the build assumptions first

Before changing anything, write down environment variables, asset paths, test tooling, TypeScript settings, proxy rules, deployment target and CI commands. This list is the migration’s real surface area, and making it explicit removes most of the surprises.

Move the build, freeze the behavior

Replace the build foundation first and keep visible behavior stable. Resist refactoring while the build is in motion. Only once the application runs on the new foundation should you start cleaning up old patterns, as a separate, reviewable step.

Run a deliberate compatibility pass

Walk through routing, forms, authentication, admin screens, analytics, feature flags, static assets and deployment previews. Treat each as a checklist item, not an assumption. This is where a migration earns the right to be called safe.

Verify through the real pipeline

Confirm the build behaves in CI and in a production-like preview, not just on a developer’s machine. The deployment path is part of the migration, not an afterthought.

Operational checklist

  • Build assumptions are written down before the migration starts.
  • The build is migrated separately from any component refactor.
  • Routing, auth, forms and admin screens are verified after the switch.
  • Environment variables and asset paths resolve identically in production.
  • CI commands and deployment previews pass on the new build.
  • Visible behavior is unchanged when the migration is declared done.

A safe path forward

Migrate the build behind your normal release process, keep the diff focused on tooling rather than features, and ship once the compatibility pass and CI both agree that nothing user-facing changed. The reward is a frontend that is easier to run, test and change, reached without forcing the team into a full rewrite.

This work is part of modernization and infrastructure rescue and sits alongside the Rails modernization checklist when the backend carries its own debt. It connects to our broader services, and the proof page frames the same careful, increment-by-increment delivery. If a slow or fragile frontend is blocking your team, tell us what is breaking.

Related services

Services connected to this article.

ModernizationRescue and modernization for systems that still have to run.

Rails upgrades, React/Vite migrations, PostgreSQL tuning, Linux production systems, NGINX, SSL, Puma, background workers, queues and deployment flows.

Need this kind of system stabilized?

Send the rough version of the problem: workflow, integration, legacy code or production pressure.

Start a conversation