What happens to a Vue 2 app after end of life?
Nothing breaks on the day itself. Vue 2 keeps working and stays downloadable, but since 31 December 2023 it receives no updates, including security and browser-compatibility fixes, according to the Vue team's official end-of-life page.
That makes Vue 2 end of life a slow risk rather than an outage. Each month, three things drift. Security: any vulnerability found in Vue 2 or in Vue 2-only libraries will not be patched upstream. Ecosystem: libraries drop Vue 2 support, so updating a date picker or chart package increasingly means you cannot. Hiring: developers who join your team learn Vue 3 patterns and find Vue 2 code, with mixins, filters and event buses, slower to work with.
The Vue team's EOL page also notes that browsers occasionally ship changes that break legacy libraries; it calls this extremely rare, but possible. For a customer-facing app, that tiny chance matters, because nobody upstream will issue a fix.
There are two responsible responses. Upgrade through a planned Vue 2 to Vue 3 migration, or, if an upgrade is truly impossible for now, buy paid extended support; the Vue EOL page points to a commercial option that continues security fixes. Doing nothing and hoping is the only irresponsible choice.
Is it safe to keep running Vue 2 in production?
For a short, deliberate period, often yes; indefinitely, no. The risk depends on what the app exposes to the internet, what data it handles and whether customers or auditors ask about unsupported software.
Score your app on four questions. Is it public, or behind a login used only by staff? Does it handle payments, health, financial or personal data? Do enterprise clients send security questionnaires that ask whether all components are supported? Do you plan significant new features in the next year? Every “yes” shortens the time you can safely wait.
An internal admin panel behind a VPN with no new features planned can wait months while you budget properly. A customer portal that handles personal data and is growing should treat the Vue 2 to Vue 3 migration as this quarter's work. Security questionnaires are an often-missed trigger: “uses end-of-life framework” can stall a sale.
- Public-facing plus sensitive data: plan the upgrade now.
- Staff-only tool, stable, no new features: schedule it, but do not wait for a crisis.
- Being rewritten within a year anyway: consider paid extended support as a bridge.
- Library updates already blocked: the cost of waiting is rising every month.
Vue 2 to Vue 3 migration: what actually breaks?
The official Vue 3 migration guide lists dozens of breaking changes, but in real codebases a handful cause most of the work: removed APIs, changed component contracts and libraries built on Vue 2 internals.
Removed outright
Filters are gone, so every {{ price | currency }} becomes a method or computed value. $on, $off and $once are removed, which kills the classic global event bus. $children and the propsData option are removed too.
Changed contracts
v-model on components uses a new prop and event name and replaces .sync. The .native modifier is removed; components declare emitted events with emits. $listeners merges into $attrs, which now also carries class and style. v-if and v-for precedence changed when both sit on one element.
Global API
new Vue() becomes createApp(), and global registrations such as Vue.use, Vue.component and Vue.prototype move onto the app instance. Plugins written the old way need adjusting.
Lifecycle and reactivity
beforeDestroy and destroyed are renamed beforeUnmount and unmounted. Watching an array for mutations now needs the deep option. data must always be a function.
The last category is the expensive one: component libraries and plugins that relied on Vue 2 internals. The official migration build documentation names Vuetify and Element UI as examples it cannot reliably support. We cover them in their own section below.
The code audit that should come before any Vue 3 upgrade estimate
Any honest estimate for a Vue 2 to Vue 3 migration comes after someone has read the code. The audit turns “we have a Vue 2 app” into a list of specific blockers, each with an effort range.
When you give us read access to the repository, we check package.json for every dependency and whether a Vue 3 version exists, the build setup (Vue CLI, webpack or Vite), the UI library and how heavily it is customised, the number of files using filters, event buses, .sync, .native and mixins, the size and shape of the Vuex store, custom directives and plugins, whether Nuxt 2 is involved, and what automated tests exist.
The output is a short written report you keep, whether or not you hire us. It lists blockers by severity, suggests a phase plan and gives an itemised estimate. Teams with in-house developers often use it as their own roadmap. We deliver it in about two working days after receiving access, and nothing is billed before you approve the written quote.
- Dependency inventory with Vue 3 availability for each package.
- Count of files using removed or changed APIs.
- UI library verdict: upgrade, replace or wrap.
- State management plan: Vuex 4 first or direct to Pinia.
- Test gaps that should be filled before touching anything.
How does the @vue/compat migration build work?
@vue/compat is a special build of Vue 3 that behaves like Vue 2 by default and prints a warning wherever your code relies on changed behaviour. The official guide says it runs in Vue 2 mode by default, with most public APIs behaving exactly like Vue 2.
Setting it up means installing Vue 3 alongside @vue/compat, aliasing vue to @vue/compat in your build tool, and enabling compatConfig: { MODE: 2 } in the compiler options. The migration guide includes examples for Vue CLI, plain webpack and Vite. Once the app boots, the browser console becomes your to-do list: each deprecation warning names the feature and links to the relevant guide entry.
The magic is granularity. Compat behaviour can be switched off per feature globally, or per component with a compatConfig option. That lets you migrate one module, flip it to full Vue 3 behaviour, test it, release it, and move on, while the rest of the app still leans on compat.
It has limits, and the official page is frank about them. Dependencies that depend on Vue 2 internal APIs or undocumented behaviour are not reliably supported. Internet Explorer 11 support is dropped entirely in Vue 3. Custom server-side rendering setups need rework beyond what the migration build covers. Knowing these limits before you start is why the audit matters.
Step-by-step Vue 2 to Vue 3 migration path for a live app
The safest order is: add tests, upgrade tooling, switch to the compat build, fix warnings in small releases, upgrade router and store, replace the UI library, then remove compat. Each step ships to production separately.
- Freeze and fence. Tag the current release, write smoke tests for login, the main dashboard and money-related flows.
- Tooling first. Upgrade the build chain, often moving to Vite, while still on Vue 2.7 if that helps.
- Swap to @vue/compat. Get the app compiling and booting on Vue 3 in Vue 2 mode.
- Fix compiler warnings. Templates first: filters,
v-model, .sync, .native, v-if/v-for. - Router and store. Move to Vue Router 4 and Vuex 4, or begin the Pinia move.
- Runtime warnings, module by module. Event buses,
$listeners, lifecycle names, array watchers. - UI library. Upgrade or replace, screen by screen, with visual checks.
- Remove compat. Drop the alias, run the full test suite, release.
Vue 2.7 deserves a mention: it backported the Composition API and <script setup> to Vue 2, so moving to 2.7 first lets you write Vue 3-style code before the switch. It is a useful stepping stone, not a destination, because it shares Vue 2's end-of-life date.
Vuex to Pinia: should state management move in the same Vue 2 to Vue 3 migration?
Not necessarily in the same release. The Vuex site says Pinia is now the new default and Vue's official state library, while Vuex 3 and 4 are still maintained but unlikely to gain new features. Vuex 4 works with Vue 3, so you can upgrade Vue first and move to Pinia after.
We usually recommend a split plan. During the core Vue 2 to Vue 3 migration, move Vuex 3 to Vuex 4, which requires small changes such as creating the store with createStore. Then convert to Pinia module by module. Pinia's own migration guide confirms that Pinia and Vuex can be mixed during the migration, so there is no big-bang moment.
What the conversion involves: each Vuex module becomes a Pinia store with an id, which replaces namespacing. Mutations disappear; their logic moves into actions, or state is assigned directly. Getters that merely return state can be deleted. Components switch from mapState and mapActions helpers to calling the store directly, or keep equivalent Pinia helpers during the transition.
Why bother at all if Vuex 4 works? Better TypeScript inference, less boilerplate, devtools support and the fact that new Vue developers learn Pinia first. For a small store the move is a day or two; for a large, tangled store it deserves its own line in the estimate.
Vue Router 3 to Vue Router 4: what changes?
Vue 3 needs Vue Router 4. The upgrade is usually modest: the router is created with createRouter and a history function, catch-all routes use a new syntax, and a few navigation behaviours changed.
In most apps we see four kinds of change. Router creation moves from new VueRouter() to createRouter() with createWebHistory() or createWebHashHistory(). The * catch-all becomes a named parameter with a custom regex. router-link props like tag and event are removed in favour of a scoped slot. And navigation now returns promises consistently, which surfaces redirect loops and unhandled rejections that Vue 2 apps silently ignored.
The last point catches teams out. Code that pushed the same route twice, or fired navigation inside guards without returning, may now log errors or behave differently. We add a test for each guard in the audit phase, so these show up before release rather than in a customer's browser.
If your app uses route-based code splitting, the () => import() pattern still works. If you used router.app or relied on the old next() callback style heavily in guards, budget a little extra time.
Upgrading Vuetify 2 and Element UI during a Vue 2 to Vue 3 migration
The UI library is usually the single largest cost in a Vue 2 to Vue 3 migration. Vuetify 2 and Element UI were built for Vue 2, and the official migration build notes it cannot reliably support libraries like them that lean on Vue 2 internals. You move to their Vue 3 versions, Vuetify 3 and Element Plus, or replace them.
Why it is expensive: component names, props, slots, grid systems and theming changed between major versions. A data table with custom slots, a form built from dozens of inputs with validation rules, or a navigation drawer with nested lists may each need rewriting against the new API. Custom SCSS overrides aimed at old class names stop matching.
We handle this screen by screen. First we list every component the app uses and how often. Then we build a small mapping sheet from old usage to new usage for your most common patterns, so fixes stay consistent. We take before and after screenshots of each screen and compare them, because a UI library upgrade that silently shifts a button can break a user's muscle memory.
Vuetify 2 to Vuetify 3
Expect changes in data tables, lists, forms and theming. Plan extra time for heavily customised data tables and any SCSS overrides.
Element UI to Element Plus
Component coverage is broadly similar, but props, events and icon handling changed. Form validation and table slots deserve careful testing.
Abandoned libraries
If a library never released a Vue 3 version, replace it with a maintained one, or write a thin component of your own if you used only a small part.
Nuxt 2 to Nuxt 3 migration notes
Nuxt 2 reached end of life on 30 June 2024, according to the Nuxt team's announcement, and receives no further security or browser fixes. Moving to Nuxt 3 is closer to a port than an upgrade, because Vue, the build tool and the server engine all change at once.
The Nuxt migration overview names three shifts: Vue 2 to Vue 3 with the Composition API and <script setup> as the default style, webpack 4 and Babel to Vite or webpack 5 with esbuild, and a runtime Nuxt dependency to a minimal standalone server compiled with Nitro. Each has knock-on effects for your code.
In practice we check data fetching first, because Nuxt 2's asyncData and fetch patterns need translating to Nuxt 3's composables. Then modules: every Nuxt 2 module needs a Nuxt 3 equivalent or replacement. Then server middleware and API routes, which move into the Nitro server directory. Then head and meta handling, which matters for SEO; we compare rendered titles, meta descriptions and canonical tags before and after on every route type.
Nuxt also offers Nuxt Bridge for teams that must stay on Nuxt 2 for a while but want some Nuxt 3 features. It can reduce risk on very large apps, though it is still a detour. Our Nuxt.js developer page covers new Nuxt work once the port is done.
Options API or Composition API after the upgrade?
Keep the Options API. Vue 3 fully supports it, and rewriting every component in the Composition API during a migration adds risk with no benefit to users. Write new code in the Composition API if your team prefers it.
This is the most common scope creep we see in a Vue 2 to Vue 3 migration. A developer, excited by <script setup>, starts rewriting working components “while we are in there”. The diff balloons, reviews slow down, and bugs appear in code that had nothing to do with the upgrade.
Our rule: the migration changes only what Vue 3 requires. Mixins that still work stay mixins for now. Once the app is on plain Vue 3 and stable, you can convert mixins to composables gradually, starting with the ones that cause naming clashes or are shared most widely. That becomes normal maintenance work, not a migration line item.
The exception is code you must touch anyway. If a component uses an event bus and filters and relies on $listeners, it may be simpler to rewrite it with the Composition API than to patch three patterns separately. We flag those cases in the audit so you can decide.
How to run a Vue 2 to Vue 3 migration on a production app without downtime
Ship the migration as a series of small releases, each tested on staging and deployable with a one-step rollback. Users should never notice a “migration day”.
Big-bang upgrades fail for predictable reasons: too many changes to review, too many screens to test manually, and no clean way back if something breaks on a Monday morning. The compat build exists precisely to avoid this, so use it.
Our release discipline for a Vue 3 upgrade looks like this. Every phase lives on its own branch and merges only after smoke tests and key-flow end-to-end tests pass. We deploy to a staging copy wired to test data, and your team clicks through a written checklist of business-critical screens. Production deploys happen early in the week at a time your users are least active, with the previous build kept ready to restore. For apps with heavy usage, we can route a small share of traffic or a group of internal users to the new build first.
Error monitoring is the final safety net. If you do not already capture front-end errors, we add a lightweight tool before the migration starts, so we can compare error rates before and after each release.
Fixed-scope or hourly: how Vue 2 to Vue 3 upgrade estimates work
A fixed-scope quote works when the audit has mapped the blockers and the codebase is well understood. Hourly billing suits messy, poorly documented code where surprises are likely. A phased mix, with the core upgrade scoped and the unknowns billed by time, often suits both sides.
Fixed scope gives you budget certainty, and the developer carries the risk of underestimating. The catch: to protect themselves, some sellers pad the figure, or define scope so tightly that every surprise becomes a change request. Hourly billing is transparent but open-ended, and it needs trust and regular progress reports.
We prefer an itemised estimate by phase after the audit. Well-understood phases, such as tooling, compat switch-over and template fixes, are estimated as defined deliverables. Uncertain phases, such as rescuing a heavily customised Vuetify data table or porting an unusual Nuxt module, are flagged with a range and the reason for the uncertainty. You approve phase by phase, so you can stop after any release with a working app. Our general thinking on billing models is on fixed price vs time and material.
Whatever model you choose, insist on written phase boundaries. “Migrate to Vue 3” is not a scope; “app runs on Vue 3 without the compat build, all listed flows pass tests” is.
Upgrade or rewrite: when is a fresh Vue 3 build smarter?
Upgrade in almost every case. A rewrite makes sense only when the app is small, the code is so tangled that nobody can change it safely, or the business needs have shifted so far that most screens would be redesigned anyway.
Rewrites are seductive because they promise clean code. They also throw away years of bug fixes and edge cases hidden in the old code, and they freeze feature work until the new version catches up. Most teams underestimate how long that takes.
Signs a rewrite might win: the app has fewer than a dozen screens, there are no tests and no original developers, the UI library is abandoned and would be replaced anyway, and a redesign is already planned. Signs you should upgrade: the app is large, works, earns money and has users who know its screens. For a rewrite, custom web app work starts from ₹60,000.
Occasionally teams ask whether to switch frameworks entirely. That is a much bigger decision than a Vue 2 to Vue 3 migration and rarely justified by the EOL alone; Vue 3 is actively maintained. If you are weighing it for hiring reasons, our page on hiring a Svelte developer discusses how framework choice affects hiring and maintenance.
Worked example: a Vue 2 to Vue 3 migration plan for a hypothetical Gurgaon dashboard
This scenario is imagined to show how an audit shapes the plan. It is not a client or a real result.
Say a logistics startup in Gurgaon runs a Vue 2.6 dispatcher dashboard built with Vue CLI, Vuetify 2 and a Vuex store of fourteen modules. Filters format dates and currency in about sixty templates, and a global event bus pushes live shipment updates between components. There are almost no automated tests. The app is staff-only but handles customer addresses and phone numbers, and a large enterprise prospect has asked whether all software is supported.
The audit would recommend six phases. First, smoke tests for login, shipment search, assignment and invoicing. Second, move to Vite on Vue 2.7. Third, switch to @vue/compat and clear template warnings, replacing filters with small formatting helpers. Fourth, Vue Router 4 and Vuex 4, and replace the event bus with a tiny emitter or a Pinia store. Fifth, the Vuetify 3 upgrade, screen by screen, starting with the least-used screens to learn the patterns. Sixth, remove compat and convert Vuex modules to Pinia one at a time.
Each phase would ship on its own, and the enterprise questionnaire could be answered honestly with a dated plan after phase three. The Vuetify data tables would carry the widest estimate range.
Vue 2 to Vue 3 migration help across India
We work remotely with product teams and businesses across India. Many Vue 2 apps date from the years when Vue was the friendly choice for small teams, so they turn up everywhere, not just in tech hubs.
We see Vue 2 dashboards at SaaS and logistics startups in Gurgaon, Noida and Pune, internal tools at IT service firms in Hyderabad, Chennai and Kochi, ecommerce admin panels in Ahmedabad and Jaipur, and ed-tech portals in Indore and Bhopal. The upgrade process is identical wherever the team sits: repository access, written audit, itemised estimate, staged releases.
We work in English and Hindi, reply on WhatsApp seven days a week, and schedule calls during IST working hours.
Vue 2 to Vue 3 migration checklist
Use this list to prepare before you talk to any developer. The more boxes you can tick, the tighter and cheaper the estimate.
- Repository access ready to share, read-only is fine for the audit.
- Current Vue, Vue Router, Vuex and UI library versions noted.
- List of business-critical flows that must never break.
- Staging environment available, or budget to create one.
- Front-end error monitoring in place, or agreed to add it.
- Browser support policy decided (Vue 3 does not support IE11).
- Nuxt 2 usage, SSR and any custom build steps documented.
- A named person on your side to test each phase on staging.
- Feature work plan agreed so it does not collide with migration branches.
- Decision on Pinia now or after the core upgrade.
If your previous developer has left and access is patchy, start with recovering a project when a developer leaves. Otherwise, share the repository via the contact page and we will begin the audit.