Migration from Vue 2 to Vue 3
This epic is created to track the current state of migrating the codebase from Vue 2 to Vue 3. We aim to outline here the list of potential blockers and track the ongoing efforts. Please keep in mind this epic is planned to be very general/shallow as we plan to be more detailed in the sub-epics / linked issues
[[_TOC_]]
## Next steps as of 2025-12-06
These are steps that aren't blocked, and can in theory be done in parallel. These are all the nodes in the [graph](#graph) with no dependencies.
- https://gitlab.com/gitlab-org/gitlab/-/issues/520987+
- ...
## Process overview
### Graph
Legend
- Gray = GitLab repo task (Not started)
- Green = GitLab repo task (Completed)
- Yellow = GitLab repo task (In progress)
- Blue = GitLab UI task
- Purple = Switchboard task
- Green outline = Non main GitLab repo task (Completed)
- Yellow outline = Non main GitLab repo task (In progress)
```mermaid
%%{init: {'flowchart': { 'nodeSpacing': 20, 'rankSpacing': 20 } } }%%
graph TD
%% Styles
classDef gitlab %% fill:#6f8,color:#fff
classDef gitlab_in_progress fill:#ffef00
classDef gitlab_complete fill:#3dc068
classDef gitlab_ui fill:#00a4ff,color:#fff
classDef gitlab_ui_in_progress fill:#00a4ff,color:#fff,stroke:#ffef00,stroke-width:10px
classDef gitlab_ui_complete fill:#00a4ff,color:#fff,stroke:#3dc068,stroke-width:10px
classDef other fill:#a2a2d0,color:#fff
classDef other_in_progress fill:#a2a2d0,color:#fff,stroke:#ffef00,stroke-width:10px
classDef other_complete fill:#a2a2d0,color:#fff,stroke:#3dc068,stroke-width:10px
classDef optional stroke-dasharray: 5 5
%% Nodes
gitlab_use_gitlab_ui_source["`Make GitLab
consume GitLab UI
source`"]:::gitlab_complete
gitlab_ui_vue_compat_package["`Publish versions
built with @vue/compat
to npm (gitlab-ui#1985)`"]:::gitlab_ui
gitlab_jest_unquarantine["`Fix all GitLab
Jest specs under
@vue/compat quarantine`"]:::gitlab_complete
gitlab_jest_unskip["`Fix all
skipped @vue/compat
GitLab Jest specs`"]:::gitlab_complete
gitlab_gdk["`Add support for
running GDK with
@vue/compat`"]:::gitlab_complete
gitlab_run_rspec["`Add support for
running RSpecs
with @vue/compat`"]:::gitlab_complete
gitlab_run_qa["`Add support for
running QA specs
with @vue/compat`"]:::gitlab
gitlab_fix_rspec["`Fix RSpecs
with @vue/compat`"]:::gitlab_in_progress
gitlab_fix_qa["`Fix QA specs
with @vue/compat`"]:::gitlab
gitlab_prod_build_vite["`Add support for
a Vite
production build
with @vue/compat`"]:::gitlab
gitlab_prod_build_vite_vue2["`Add support for
a Vite
production build
with Vue 2`"]:::gitlab
gitlab_prod_build_webpack["`Add support for
a Webpack
production build
with @vue/compat`"]:::gitlab
gitlab_feature_flagged_builds["`Add support for
feature flagged
asset builds`"]:::gitlab
class gitlab_feature_flagged_builds optional
switchboard_drop_compat_flags["`Drop compat flags
in Switchboard`"]:::other
switchboard_vue3["`Switch to Vue 3
in Switchboard`"]:::other
gitlab_drop_vue2["`Drop support for
Vue 2 in GitLab`"]:::gitlab
gitlab_ui_drop_vue2["`Drop support for
Vue 2 in GitLab UI`"]:::gitlab_ui_in_progress
gitlab_ui_drop_compat_flags["`Drop compat flags
in GitLab UI`"]:::gitlab_ui_in_progress
gitlab_drop_compat_flags["`Drop compat flags
in GitLab`"]:::gitlab
gitlab_vue3["`Switch to Vue 3
in GitLab`"]:::gitlab
gitlab_ui_vue3["`Switch to Vue 3
in GitLab UI`"]:::gitlab_ui
%% Dependencies - kill webpack first
gitlab_gdk --> gitlab_run_rspec
gitlab_gdk --> gitlab_run_qa
gitlab_feature_flagged_builds -.-> vite_or_webpack
switchboard_drop_compat_flags --> switchboard_vue3
switchboard_vue3 --> gitlab_ui_vue3
gitlab_jest_unquarantine --> gitlab_drop_vue2
gitlab_jest_unskip --> gitlab_drop_vue2
gitlab_run_rspec --> gitlab_fix_rspec --> gitlab_drop_vue2
gitlab_run_qa --> gitlab_fix_qa --> gitlab_drop_vue2
vite_or_webpack --> gitlab_drop_vue2
gitlab_drop_vue2 --> gitlab_drop_compat_flags --> gitlab_vue3
gitlab_drop_vue2 --> gitlab_ui_drop_vue2
gitlab_ui_drop_vue2 --> gitlab_vue3 --> gitlab_ui_vue3
gitlab_ui_package ---> gitlab_gdk
gitlab_drop_vue2 --> gitlab_ui_drop_compat_flags --> gitlab_ui_vue3
gitlab_ui_drop_compat_flags --> switchboard_vue3
gitlab_ui_drop_compat_flags --> gitlab_vue3
subgraph gitlab_ui_package["Either"]
direction LR
gitlab_use_gitlab_ui_source
gitlab_ui_vue_compat_package
end
subgraph vite_or_webpack["Either"]
direction LR
subgraph vite["Vite"]
direction LR
gitlab_prod_build_vite_vue2 --> gitlab_prod_build_vite
end
subgraph webpack["Webpack"]
gitlab_prod_build_webpack
end
end
```
### Step 0: pre-migration
- [x] remove the outdated `slot`/`slot-scope` attributes
- [x] main codebase (https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64604 by @ntepluhina)
- [x] GitLab UI
- Mostly done in https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2269
- [x] Several chart components still use the deprecated slot syntax, and require particular attention due to more complex slot definitions and incomplete test coverage (see https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2269#note_612928917)
- [x] set up linter rules to prevent deprecated APIs from being used (https://gitlab.com/gitlab-org/frontend/eslint-plugin/-/merge_requests/50#note_610914212 by @markrian)
- [x] check how unit tests work with compat build and evaluate the effort for VTU 1 -> 2 migration
- VTU 1 --> 2 migration could be mostly automated with codemods, however it is possible only when
- [x] evaluate the effort of making class-based stores reactive
- [x] check how Vuex works in compat build and evaluate the effort for Vuex v3 -> v4 migration
- [x] check how VueApollo works in compat build and evaluate the effort for VueApollo 3 -> 4 migration
- [x] check how Vue Router works in compat build and evaluate the effort for v3 -> v4 migration
- [ ] evaluate Vue-related non-core dependencies in terms of their readiness for migration / working in compat build
### Step 1: "Vue3-friendly". Utilize `@vue/compat` for migration
Child epic: https://gitlab.com/groups/gitlab-org/-/epics/9013+
At this point we want all our Vue-related project use `@vue/compat`:
* [x] https://gitlab.com/gitlab-org/gitlab-ui (epic: https://gitlab.com/groups/gitlab-org/-/epics/7203)
* [ ] https://gitlab.com/gitlab-org/gitlab (epic: TBD)
* [ ] https://gitlab.com/gitlab-org/status-page (epic/issue: TBD)
* [ ] https://gitlab.com/gitlab-org/customers-gitlab-com/ (epic: https://gitlab.com/groups/gitlab-org/-/epics/10121)
* [ ] https://gitlab.com/gitlab-org/gitlab-design (epic: TBD)
* [x] https://gitlab.com/gitlab-com/gl-infra/gitlab-dedicated/switchboard (epic: TBD)
At this point we will be relying on [vue-test-utils-compat](https://www.npmjs.com/package/vue-test-utils-compat) to make our test suite compatible with Vue2 and `@vue/compat`. Our codebase should be tested and verified both with Vue2 and Vue3 with feature flag (or similar approach) flipping usage of vue version when needed
Known blockers outside of GitLab:
* [x] `bootstrap-vue` release with `@vue/compat` https://github.com/bootstrap-vue/bootstrap-vue/pull/6905
* [x] `@vue/test-utils` release with https://github.com/vuejs/test-utils/pull/1804 merged
### Step 2: "Vue3-first". Drop Vue.js 2 support (per project)
After ensuring everything is working with `@vue/compat` each project **independently** will take decision to drop Vue2 support. `gitlab-ui` will be the last one as long as there will be no vue2-based consumers
At this point we will move [vue-test-utils-compat](https://www.npmjs.com/package/vue-test-utils-compat) from being application-wide to specific explicit initialization in each test suite. This will allow us to write tests using `@vue/test-utils v2` while not being forced to rewrite all tests to `@vue/test-utils-v1`. For old tests we will switch compat flags one-by-one, applying codemods with fixes (approx. 80% of test suide could be automatically migrated to `@vue/test-utils v2` automatically)
Also we will start migrating codebase to Vue3 by acting both horizontally and vertically. Under **vertical** migration we are considering disabling **compat flags** in `@vue/compat` one-by-one and performing mostly automated conversions to our codebase. Under **horizontal** migration we're considering migrating existing components to Vue3 by adding: `{ compatConfig: { MODE: 3 }}` to components. These approaches will take place simultaneously and decision will taken on per-case basics
### Step 3: Switch `@vue/compat` to `vue` (per project)
As soon as `@vue/compat` will have all compat flags switched off, we should be able just swap `@vue/compat` with `vue` and be ready to go
epic