skip to content

You lead a large Vue 2.6 app with custom SSR, a Vue 2-only component library and many mixins; how would you plan and stage its move to Vue 3?

level: principalimportance: should knowfreq 30%

answer

  1. eligibility before effort
  2. the blockers the guide names
  3. a style upgrade, then a runtime upgrade
  4. ship on the bridge
  5. exit criteria for the alias

basics

~20 s

Audit eligibility first: dependencies on Vue 2 internals, IE11 and custom SSR block the migration build. Go to 2.7 for Vue 3-style new code, resolve the blockers, then ship on @vue/compat and move components to MODE 3 until it can go.

solid answer

~50 s

There is no single right plan; I would stage it around the migration build's known blockers. **Audit** first: a component library built on Vue 2 internals needs a Vue 3 version or a replacement; custom SSR moves from `vue-server-renderer` to `@vue/server-renderer` with no bundle renderer, the most involved piece; IE11 would stop the plan outright. **Stage one** is Vue 2.7: new code in `<script setup>`, mixins extracted into composables, and wrapper components around the library so it can be swapped behind stable APIs. **Stage two** resolves the blockers, including the SSR rewrite. **Stage three** runs on `@vue/compat` in production, upgrades the store and router, and moves components to `MODE: 3`, tracking warning IDs as the progress metric. The trade-offs are time spent on the bridge versus a risky big-bang switch, and the security exposure of running Vue 2 past its December 31st, 2023 end of life.

go deeper

for a junior

Know that big Vue 2 apps usually move in stages, starting with Vue 2.7 and then running on the @vue/compat build.

for a middle

Name the blockers the migration guide lists: dependencies on Vue 2 internals, IE11 and custom SSR, and explain why each changes the plan.

for a senior

Lay out the staged plan with concrete steps: 2.7 and composables, wrapper components around the library, the SSR rebuild, the compat switch and per-component MODE 3.

for a principal

Own the trade-offs: time on the bridge versus a big-bang switch, end-of-life exposure, funding the burn-down, and clear exit criteria that let the team remove the alias with confidence.

## Start with eligibility, not effort The migration build (`@vue/compat`) only covers **documented Vue 2 behaviour**, and the migration guide names the situations it cannot rescue. A plan starts by checking each against the app: - **Dependencies on Vue 2 internals** — the most common case is private VNode properties. A component library built that way will not run on the migration build; it needs a Vue 3-compatible version or a replacement. - **Custom SSR** — possible, but much more involved: `vue-server-renderer` is replaced by `@vue/server-renderer`, and Vue 3 has **no bundle renderer**, so the server entry and build pipeline change shape. - **IE11** — Vue 3 does not support it. If the requirement is real, the answer is to stay on Vue 2 and manage that risk, not to plan a migration. In this scenario the first two apply, and they, not the number of components, decide the schedule. ## Options on the table | strategy | fits when | main cost | |---|---|---| | 2.7 first, then compat build, shipping as you go | blockers can be resolved one at a time | a long period on the bridge, with its overhead and discipline | | big-bang upgrade on a long-lived branch | small app, few dependencies | merge pain, feature freeze, one risky release | | stay on Vue 2 | a hard blocker such as IE11 | running past end of life without upstream fixes | For a large app with active feature work, the first row is usually the defensible choice. ## A staged plan 1. **Stage 0: inventory.** List Vue 2-only dependencies, SSR entry points, global API use (`Vue.use`, `Vue.prototype`, `new Vue`), filters, event-bus `$on` use, and mixins. Run a spike on the migration build to see how far the app gets. 2. **Stage 1: Vue 2.7.** Upgrade the minor version. Write new components with `<script setup>` and the Composition API, and extract mixins into composables — mixins still work in Vue 3, but their `data` merge becomes shallow, and composables remove the name-collision problem. 3. **Stage 2: isolate the library.** Put your own wrapper components between the app and the Vue 2-only library, so replacing it later touches wrappers rather than hundreds of call sites. 4. **Stage 3: clear the blockers.** Upgrade or replace the library behind its wrappers, and rebuild the SSR entry on `@vue/server-renderer`. This is where most risk lives, so it gets its own releases and rollback plan. 5. **Stage 4: switch to the migration build.** Alias `vue` to `@vue/compat`, fix compile-time errors, rename transition classes, move to `createApp`, upgrade the store and router to their Vue 3 versions, and **ship to production** on compat. 6. **Stage 5: burn down.** Work the warnings per deprecation ID, move converted components to `compatConfig: { MODE: 3 }`, then flip the global default to `MODE: 3` and finally remove the alias. The component tests move with the runtime: Vue Test Utils 2 is the Vue 3 line, and its migration notes list the mounting-option changes. ## Measuring progress and deciding when to stop - **Warning IDs remaining**, collected from dev and test runs, since production builds print none. - **Components in `MODE: 3`**, or the share covered by a global `MODE: 3` with named exceptions. - **Dependencies still needing Vue 2 behaviour** — each is an explicit blocker for removing the alias. - **Exit criterion**: the app runs under global `MODE: 3` with no features re-enabled, and the alias can be removed without behaviour changes. ## Risks and trade-offs a lead has to own - **Time on the bridge** versus a big-bang switch: the bridge keeps releases flowing, but only if the burn-down keeps being funded. - **End of life**: Vue 2 has had no upstream fixes since December 31st, 2023; the longer stages 1 to 3 take, the longer that exposure lasts, which may justify buying extended support for the interim. - **Silent changes**: the transition class rename emits no warning, and production builds print no deprecation warnings at all, so test coverage and review carry that load. - **Parallel work**: new features written in Vue 3 style from stage 1 onward keep the migration from falling behind the codebase it is migrating.

  • How would you report progress on the migration build to stakeholders?
    With counts that only move one way: remaining deprecation IDs from dev and test runs, components switched to `MODE: 3`, and the list of dependencies still needing Vue 2 behaviour. The finish line is concrete — the app runs under global `MODE: 3` with nothing re-enabled — so the alias can be removed.
  • When would you recommend not migrating yet?
    When a hard requirement such as IE11 support exists, or when a critical Vue 2-only dependency has no Vue 3 path and no replacement budget. Then the decision is how to run Vue 2 past its end of life: accepting the risk, buying extended support, and reducing exposure while planning a later move.

saying these in an interview costs you the question

  • Commit to the compat-build plan before checking dependencies for Vue 2 internals.
  • The migration build handles a custom SSR setup the same way as client code.
  • No Vue 3 code can reach production until the whole migration is finished.
  • Staying on Vue 2.7 is risk-free because it is in maintenance mode.
  • Every mixin must be rewritten before the app can run on Vue 3.