Frontend migration

Vue 2 to Vue 3 migration and end-of-life frontend upgrades

A Vue 2 to Vue 3 migration – like any move off an end-of-life frontend framework – goes best in small steps that ship to production every week. Vue 2 reached end of life on December 31, 2023 and AngularJS support ended at the end of 2021, so both no longer receive security fixes. I move your frontend incrementally, screen by screen, rather than freezing the product for a rewrite.

The approach is the same one I use for legacy modernization on the backend: put a seam in, move one slice at a time, delete the old code as you go.

How I run a Vue 2 to Vue 3 migration

  1. Get to Vue 2.7 first. It backports the Composition API and script setup, so new and refactored components can be written in Vue 3 style while you’re still on Vue 2.
  2. Swap the build to Vite if you’re on Vue CLI or a custom webpack setup. It’s an independent change and makes everything after it faster to iterate on.
  3. Audit the blockers. UI component libraries and plugins without Vue 3 versions are usually the long pole. Each one gets a decision: upgrade, replace or wrap.
  4. Switch to the migration build. @vue/compat runs Vue 3 with Vue 2 behavior switched on, logging a warning each time deprecated behavior is used. The app works on day one; the warnings become the to-do list.
  5. Burn down the warnings component by component: filters become methods or computed properties, the $on and $off event bus becomes a small emitter like mitt or shared state, v-model on components moves to modelValue, $listeners folds into $attrs.
  6. Upgrade the ecosystem. Vue Router 4 or later, and Vuex 4 or a move to Pinia. Pinia is optional – don’t bundle it with the framework upgrade unless the store is already a problem.
  7. Remove compat mode once the warnings are gone, and turn it off per component along the way using compatConfig.

AngularJS migration: Angular, React or Vue?

AngularJS is a different framework from modern Angular, so “AngularJS to Angular migration” is a rewrite of every component either way. Choose the destination based on your team and hiring, not on which is closest:

  • AngularJS to Angular with ngUpgrade: run both in one hybrid app, downgrade new Angular components into AngularJS templates, and migrate services and routes over time. Familiar concepts like dependency injection carry over.
  • AngularJS to React by mounting React components inside AngularJS directives (react2angular or a small wrapper), then moving whole routes to React once enough pieces exist. Shared state goes through a plain store both sides can read.
  • Route by route behind the server. If the app has clearly separate sections, serve migrated routes from the new app and the rest from the old one. This is the strangler fig pattern at the URL level.

jQuery to React migration with islands

Server-rendered apps with jQuery sprinkled through the templates don’t need a single-page app. Mount React (or Vue, or Preact) as islands: a component rendered into a specific element on an existing page, receiving its initial data from a data attribute or JSON script tag. Start with the most interactive, most bug-prone widget.

Over time the islands grow and the jQuery shrinks. Many products never need to go further, and that’s a fine outcome – server rendering is cheaper and faster than many SPAs that replace it.

Why not a big-bang rewrite?

Rewriting the frontend in a new framework sounds contained, but it carries every risk of a backend rewrite: hidden behavior, a moving target, and nothing shipped until the end. Incremental migration delivers value from week one and can pause whenever product work takes priority. I’ve made the longer argument in rewrite vs refactor.

I’m also wary of reaching for micro-frontend frameworks like single-spa or module federation just to run two frameworks side by side. Islands or a hybrid app usually do the job with far less infrastructure.

What I need from you

Access to the repo, a staging environment, and someone on your team who’ll own the frontend afterwards. Some end-to-end tests on critical flows (Playwright or Cypress) help a lot – if there aren’t any, writing a few for checkout, sign-up and the core workflow is the first thing I do.

Questions

When did Vue 2 reach end of life?

Vue 2 reached end of life on December 31, 2023. It no longer receives security fixes or updates from the core team. Commercial extended support exists, but for most teams the better investment is moving to Vue 3 with the migration build.

How long does a Vue 2 to Vue 3 migration take?

It depends mostly on third-party dependencies and component count. With the compat build the app runs on Vue 3 early, and the remaining work is clearing warnings component by component alongside normal feature work. Libraries without a Vue 3 version are usually what stretches the timeline.

Should we migrate AngularJS to Angular or React?

Choose based on your team’s skills and hiring market rather than which framework seems closer. Both require rewriting every component. Angular’s ngUpgrade gives a well-trodden hybrid path; React offers a larger ecosystem and hiring pool.

Do we need micro-frontends to migrate incrementally?

Rarely. Mounting new components as islands inside the old app, or splitting by route at the server, achieves incremental migration with much less infrastructure. Micro-frontends make sense when several teams need to deploy frontend parts independently.

Frontend stuck on an end-of-life framework?

Tell me the framework, the rough size of the app and your blockers. In a two-week sprint I’ll set up the migration path and ship the first migrated screens.

GMT+2 · Full EU overlap · US East mornings

Related