Preparing your project

Before we touch the code, there's a few things to do to prepare your project to run Vue 3 code.

Create a new Branch
Upgrade Dependencies
Bundler Setup
Vue Devtools
Eslint Setup

Create a new Branch

This step is hopefully obvious, but:

Do all migration work in a new branch

  1. Never start migrating directly on you main or development branch. You want to be able to pause migration, switch back to your Vue 2 codebase to work in a fix, for example, and then return to your migration branch to continue migrating to Vue 3.
  2. If migration takes some time, frequently rebase the migration branch back on the main/dev branch so they don't get out of sync too much.

Dependencies

In a typical Vue project, a lot of additional tools, like bundlers, test runners, and linters are used, so Vue itself isn't the only dependency we have to upgrade. The following is a list with all of the official Vue libraries that you might be using in your project and their respective Vue3-compatible versions.

PackageTarget versionNotes
vuev3.vuejs.org
vue-template-compiler-/-replaced by @vue/compiler-sfc
@vue/compiler-sfcreplaces vue-template-compiler
vue-routernext.router.vuejs.org
vuexnext.vuejs.org
@vue/cli-*automatically configures vue-loader@16
vue-loader
eslint-plugin-vuecomes with deprecation warnings, see below
@vue/test-utilsvuejs.github.io/vue-test-utils-next-docs/
vue-jest
Vetur VS Code Extension^0.29
Running `yarn upgrade-interactive --latest` doesn't necessarily give you the Vue 3 compatible versions, since at the time of writing, a good number of these releases are still on the `next` tag on npm, not the default `latest` tag.

Likewise, yarn add vue will still install ^2.6.*, for example, until Vue 3 has been moved to the latesttag.

Vue CLI

Vue CLI projects with official @vue/cli-* dependencies matching ^4.5.0 come with full Vue 3 support. There's no need to upgrade or configure vue-loader, so usually don't need to apply the changes explained in the rest of this page.

However, you will still need to upgrade all of the dependencies in your project's package.json files according to the above table.

Library projects / rollup

This guide focusses on migrating Vue apps, which usually use webpack in their build setup. If you are using rollup in your app, or want to migrate a Vue library or plugin to Vue 3, this guide might still over a lot of relevant information, but doesn't necessarily address all points relevant to such a project.

in Rollup projects that contain .vue files, eslint-plugin-vue is used to compile these SFCs. that library has also had a new Release for Vue 3 compatibility.

We won't cover this in any detail here, as we focus on a typical medium-to-large app project, which are usually powered by Webpack / Vue CLI

PackageTarget versionNotes
rollup-plugin-vueusually used for bundling plugins/libraries

Webpack

If you are running a custom webpack setup, there are a few quick changes necessary to bring your build system up to speed with the new Vue version.

vue alias

You likely have an alias defined in your webpack config, to point the 'vue' import to the right dist version of Vue:

{
 resolve: {
   alias: {
     // if you only need compile-time compilation of templates (.vue files)
     'vue$': 'vue/dist/vue.esm.js',
     // if you need runtime-compilation of templates
     'vue$': 'vue/dist/vue.runtime.esm.js',
   }
 }
}

Naming of the different dist versions has changed in Vue 3 (read more). So your aliases should be changed to point to the matching new file names:

{
 resolve: {
   alias: {
     // if you only need the runtime without the template compiler
     // i.e. only use .vue files which are compiled at build-time.
     'vue$': 'vue/dist/vue.runtime.esm-bundler.js',
     // if you need runtime-compilation of templates included in the bundle
     'vue$': 'vue/dist/vue.esm-bundler.js',
   }
 }
}

vue-loader

Vue Loader options changed a bit (v15 vs v16), but usually, the only thing you might need to take care of is to pass any additional babel plugins that you want to apply to the script section as an additional option, i.e:

{
 module: {
   rules: [
     {
       test: /.vue$/,
       use: {
         loader: 'vue-loader',
         options: {
           babelParserPlugins: ['jsx', 'classProperties', 'decorators-legacy']
         }
       }
     }
   ]
 }
}

Devtools

The devtools have also completely rewritten while working on Vue 3 support for them This new version will eventually support Vue 2 as well, but for now, during the pre-release phase, it's available as a separate extension here:

Vue Devtools Beta in the Chrome Store

Install this to get devtools support for the Vue 3 app. You can run this alongside the normal Vue Devtools extension for Vue 2, they don't conflict.

As of the time of this writing, the devtools are still missing support for VueRouter and Vuex, but those are already in development , making use of the new plugin architecture that the Vue Devtools provides.

Learn more

Eslint Migration warnings

eslint-plugin-vue@7.0.0 comes with support for Vue 2 and Vue 3, it offers rule sets for both versions.

It is highly recommended to use eslint during a migration as Vue 3 rule sets come with deprecation warnings. These rules will have eslint throw eslint warnings or errors when it comes across features or APIs in your component that need some sort of Migration activity on your end.

Example of an eslint rule warning about removed 'functional' attribute on template tags

While these rules catch a lot of the changes that have to do, they won't catch all of them, so don't rely on them exclusively.

Make sure to follow they guide laid out in the following parts and turn to the official Migration guide if you come across any problems that this guide here might not cover.

A typical eslint config using eslint-plugin-vue might look like this:

.eslintrc.js
module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: [
    // note the "vue3-" prefix 
    'plugin:vue/vue3-strongly-recommended',
    'eslint:recommended',
    '@vue/prettier',
  ],
  parserOptions: {
    parser: 'babel-eslint',
  },
}
If your project uses something like `lint-staged` to lint code before it's allowed to be committed to git, you might find yourself in a situation where you want to commit code for a component that still contains pieces of code that these deprecation rules warn about.

You can to turn off these rules before commits, and turn them back on when you continue to fix stuff - or you just make sure to fix all stuff within a component at once when you come across it.