Migrating Legacy Vue 2 Projects to Vue 3

A practical guide to migrating legacy Vue 2 applications to Vue 3, covering component refactoring, UI consistency, testing updates, and build tool modernization.

Migrating Legacy Vue 2 Projects to Vue 3

Transitioning a large-scale legacy Vue 2 project to Vue 3 can be challenging — especially when the codebase has grown over years of incremental changes. This article outlines a systematic approach to refactoring components, maintaining UI consistency, updating tests, and modernizing the build system using Vite.


1. Component Refactor

Vue 3 introduces the Composition API, new lifecycle hooks, and a redefined reactivity system. When migrating:

  • Incremental Refactoring: Start with leaf components before tackling core layouts or global state.
  • Script Setup Syntax: Simplify your components with <script setup> for cleaner and more concise code.
  • Reactive APIs: Replace data() and methods with ref, reactive, and composables.
  • Deprecations: Watch for removed APIs such as filters, inline-template, and $on/$off.

💡 Tip: Use the official Vue 2 to Vue 3 Migration Build to run your app in a compatibility mode and progressively refactor.


2. UI Consistency

Visual consistency is often disrupted during a major migration. To ensure your UI remains stable:

  • Design Tokens: Centralize colors, spacing, and typography to avoid CSS drift.
  • Component Libraries: If using libraries like Vuetify or Element UI, check for Vue 3–compatible versions.
  • Snapshot Testing: Capture pre- and post-migration visuals with tools like Percy or Chromatic.
  • Accessibility: Revalidate ARIA attributes and event handling — the event model in Vue 3 has subtle differences.

3. Updating and Maintaining Tests

Testing must evolve with the framework changes:

  • Testing Library: Switch from vue-test-utils (v1) to @vue/test-utils@next.
  • Mocking & Events: Update event mocks since $emit and listeners behave differently.
  • E2E Tests: Re-run and validate with Cypress or Playwright to catch integration issues.
  • Snapshot Updates: Refresh component snapshots to reflect new render outputs.

⚙️ Refactoring without updating tests is risky — make test parity a migration milestone.


4. From Webpack to Vite

Moving from Webpack to Vite offers faster dev builds and modern ES module support:

  • Config Simplification: Migrate loaders and plugins to Vite’s plugin system (vite-plugin-vue2 / vite-plugin-vue).
  • Alias & Env: Convert resolve.alias and .env files to Vite syntax.
  • Legacy Browser Support: Use the @vitejs/plugin-legacy plugin if you still need IE11 compatibility.
  • Hot Reload: Vite’s native HMR reduces build times drastically for large Vue codebases.

Conclusion

Migrating from Vue 2 to Vue 3 is not a single-step upgrade — it’s a progressive modernization journey.
Approach it with a clear roadmap: start small, test thoroughly, ensure UI consistency, and take advantage of modern tooling like Vite.

🧩 The goal isn’t just compatibility — it’s to unlock Vue 3’s performance, scalability, and developer experience benefits while keeping your legacy project maintainable.


Written on October 28, 2025 — inspired by the Agentic Design Pattern for collaborative, multi-agent code transformation workflows.