Skip to main content
10 min readEngineering

Migrating a 50+ Component Admin Portal from Vue 2 to Vue 3

Lessons from migrating a production admin portal to Vue 3 — dependency mapping, mixin refactoring, incremental adoption strategy, and what I'd do differently.

SK

Sharath Kumar K R

Senior Software Engineer

Share
Vue 3MigrationTypeScriptComposition API

Our admin portal had grown for years with Vue 2 and the Options API. Fifteen global mixins with complex interdependencies, 8 class components using vue-property-decorator, 27 custom directives, and 50+ components across 3 application modules. Vue 2 was approaching EOL, and TypeScript support was painful. The migration wasn't optional.

Strategy: Incremental, Not Big Bang

We used the Vue 2 → Vue 3 compatibility build to run both versions side-by-side. The key was a strict dependency graph: we mapped every component's dependencies and migrated leaf nodes first, working inward. A custom script revealed hidden circular dependencies in our mixin composition that would have broken silently in Vue 3.

The three-phase approach:

  1. Audit and refactor: Built a dependency graph of the entire component tree. Refactored circular mixin dependencies while still on Vue 2.
  2. Upgrade infrastructure: Updated Vue CLI to Vite, enabled TypeScript strict mode, configured the compatibility build. Two weeks of zero user-facing changes.
  3. Migrate components: Utility composables first, then leaf components, then containers. Each migration: extract logic into composables, replace mixins, convert to setup syntax.

Key Lessons

  • Mixins are the primary migration challenge. They hide dependencies in ways that break silently. Audit them first, replace them with composables while still on Vue 2.
  • TypeScript strict mode catches migration bugs the compatibility build misses. Enable it before migrating components.
  • Playwright tests running against both builds verify identical behavior before and after migration.
  • Composables are not just better mixins — they're a fundamentally different composition model. Train your team before the migration starts.

The migration took 4 months alongside feature development. We shipped zero Vue 3-related production bugs. Component complexity reduced by 30%. TypeScript adoption went from 40% to 95%. The team unanimously prefers the new architecture.