Skip to content
TutorialProjects & tooling

Editor and Vue DevTools setup in 2026

One editor extension, one formatter, one linter and Vue DevTools. This is the setup we recommend this September, file by file, with a checklist that proves each part is working.

vuejs.school team15 Sep 20268 min readVue (Official) extension 3.3 · Vue DevTools 8.2 · Vite 8.3

A good setup catches a typo in a template before you save, formats the file when you do, and lets you look inside the running app without adding console.log everywhere. You will configure VS Code for Vue, run Vue DevTools in the browser, and finish with a short checklist that confirms each part works on your machine.

Everything here is checked against the Vue (Official) extension 3.3.11, Vue DevTools 8.2.1, Vite 8.3, ESLint 10 and the files that create-vue 3.23 generates. If you scaffold with npm create vue@latest and tick ESLint and Prettier, most of these files are written for you. This post explains what they do, so you can fix them when they break.

Install the editor extensions

You need three extensions in VS Code:

  • Vue (Official), ID Vue.volar. It understands .vue files: highlighting, completion for components and props, type errors inside templates, go to definition.
  • ESLint, ID dbaeumer.vscode-eslint. It shows lint problems as you type and fixes them on save.
  • Prettier, ID esbenp.prettier-vscode. It formats the file when you save.

If an old project still recommends Vetur, the extension for Vue 2, disable it. Two extensions fighting over the same .vue file give you duplicate errors and a slow editor.

Put the list in the project, so everyone who opens the folder is offered the same set:

.vscode/extensions.json
{
  "recommendations": ["Vue.volar", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
}

On JetBrains IDEs the picture is simpler. WebStorm ships Vue support in its bundled Vue.js plugin, so there is nothing to install; check that the plugin is enabled under Settings, Plugins. Turn on ESLint and Prettier under Languages & Frameworks, choose automatic configuration for both, and tick their "on save" options. The DevTools half of this post is identical, because DevTools lives in the browser.

Format on save: Prettier or Oxfmt

A formatter rewrites spacing, quotes and line breaks to one consistent style, so code review is about code. Use Prettier. It has been stable for years, the 3.9 line is current, and create-vue offers it as a regular option. With Prettier and ESLint ticked, create-vue writes these two files (its settings file also has a few explorer.fileNesting lines, left out here):

.prettierrc.json
{
  "$schema": "https://json.schemastore.org/prettierrc",
  "semi": false,
  "singleQuote": true,
  "printWidth": 100
}
.vscode/settings.json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll": "explicit"
  }
}

formatOnSave runs the formatter every time you save. defaultFormatter tells VS Code which extension wins, because Vue (Official) can also format .vue files block by block and you only want one formatter in charge.

codeActionsOnSave is where ESLint's fixes come in. source.fixAll asks every extension that offers automatic fixes, ESLint included, to apply them when you save; "explicit" limits that to saves you make yourself, not VS Code's auto-saves.

Oxfmt is the newer option, a formatter written in Rust by the Oxc project. Its beta announcement reports it as more than 30 times faster than Prettier on a first run without a cache, and it formats Vue files. create-vue 3.23 lists it under experimental features, with the oxc.oxc-vscode extension as the default formatter. It is a sensible choice for a large codebase where Prettier is slow, as long as you accept beta software in your toolchain.

Lint in the editor with ESLint 10

ESLint 10 reads one format only: the flat config file, eslint.config.ts or eslint.config.js. The VS Code extension follows it automatically, so two old settings can go:

  • eslint.useFlatConfig is ignored from ESLint 10 onwards.
  • eslint.validate is not needed for .vue files, because vue is already in the extension's default eslint.probe list.

If an old settings file still has either one, delete it.

When you combine ESLint with a formatter, ESLint must stop judging formatting, or the two will argue about every semicolon. create-vue adds one line for that:

eslint.config.ts
import { globalIgnores } from 'eslint/config'
import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'
import pluginVue from 'eslint-plugin-vue'
import skipFormatting from 'eslint-config-prettier/flat'

export default defineConfigWithVueTs(
  {
    name: 'app/files-to-lint',
    files: ['**/*.{vue,ts,mts,tsx}'],
  },

  globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),

  ...pluginVue.configs['flat/essential'],
  vueTsConfigs.recommended,
  skipFormatting,
)

skipFormatting switches off every rule that a formatter already handles. It goes last, so nothing after it turns those rules back on. create-vue uses the same line with Oxfmt.

A create-vue project also has ...pluginOxlint.buildFromOxlintConfigFile('.oxlintrc.json') just before skipFormatting. create-vue 3.23 always adds Oxlint, a second linter from the Oxc project, when you tick ESLint, and that entry turns off the ESLint rules Oxlint already runs. Oxlint's own findings appear in the editor through the Oxc extension (oxc.oxc-vscode), which create-vue adds to extensions.json.

Stay on TypeScript 6.0 in Vue projects

Vue (Official) has two halves. A Vue language server handles templates and styles, and a TypeScript plugin, @vue/typescript-plugin, runs inside VS Code's own TypeScript service and lets it understand .vue files, so TypeScript works in your components and in the .ts files that import them. Leave the built-in "TypeScript and JavaScript Language Features" extension switched on; the plugin depends on it.

Do not switch a Vue project to TypeScript 7 yet. TypeScript 7.0, the compiler rewritten in Go, came out on 8 July. Its announcement says plainly that tools which embed TypeScript, Volar included, still rely on TypeScript 6.0, and that Vue projects need to stay on 6.0 for editor support for now. create-vue 3.23 stays on 6.0 too: it installs typescript ~6.0.0 next to vue-tsc 3.3. If you installed the TypeScript 7 extension for VS Code, run "Disable TypeScript 7 Language Server" from the command palette in Vue workspaces.

Then point VS Code at the project's own TypeScript, so the editor and vue-tsc agree. Add "typescript.tsdk": "node_modules/typescript/lib" to the same settings file, then run "TypeScript: Select TypeScript Version" and choose the workspace version.

Add a snippet for new components

The extension already completes component names, props, events and directives, and it suggests the const props = assignment when you type defineProps. What it cannot guess is the skeleton of a new file. A project snippet file in .vscode/ fixes that, and once it is committed the whole team gets it:

.vscode/vue.code-snippets
{
  "Vue component with typed props": {
    "scope": "vue",
    "prefix": "vsfc",
    "body": [
      "<script setup lang=\"ts\">",
      "const props = defineProps<{",
      "  ${1:title}: string",
      "}>()",
      "$0",
      "</script>",
      "",
      "<template>",
      "  <h2>{{ props.${1:title} }}</h2>",
      "</template>"
    ],
    "description": "Single-file component with script setup and typed props"
  }
}

Type vsfc in an empty .vue file and press Tab. ${1:title} is the first stop, and both places update as you type. $0 is where the cursor ends. "scope": "vue" keeps the snippet out of other file types. Write snippets for the shapes you repeat; three good ones beat a downloaded pack of fifty.

Vue DevTools: browser extension or Vite plugin

Vue DevTools lets you see the component tree, the state of each component, your Pinia stores and your routes while the app runs. It comes in two forms. Version 8 supports Vue 3 only.

The browser extension is installed once from the Chrome Web Store or Firefox Add-ons (Edge, Brave and Arc use the Chrome one). It works on any Vue 3 app running in development mode and opens as a "Vue" tab in the browser's own developer tools.

The Vite plugin runs inside your app instead, and the Vite plugin guide recommends it for Vite projects because it offers features the extension does not have. create-vue installs it by default. In an existing project, run npm install -D vite-plugin-vue-devtools and add it to the config:

vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'

export default defineConfig({
  plugins: [vue(), vueDevTools({ launchEditor: 'code' })],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
})

launchEditor decides which editor opens when you click "open in editor" on a component. 'code' is the default; use 'webstorm' for WebStorm. VS Code also needs its code command on your PATH. The plugin supports Vite 6, 7 and 8, so Vite 8.3 is fine.

Run npm run dev. Below the local URL, the terminal prints two extra lines: one with a /__devtools__/ address that opens DevTools as a separate window, and one telling you to press Option+Shift+D (Alt+Shift+D on Windows and Linux) to toggle the in-page overlay.

What each DevTools panel is for

  • Components shows the tree. Select a component to see its props, state and computed values, and edit a value to watch the page update.
  • Inspector (Vite plugin only) lets you point at anything on the page and see which component rendered it.
  • Pinia lists your stores and lets you edit their state. With Pinia 4, @vue/devtools-api is a peer dependency you install yourself; if the panel is missing, run npm install @vue/devtools-api.
  • Router lists every route with its details, and Pages lets you type a path and see which route matches.
  • Timeline records events over time, including rendering and updates, so you can see what happened in which order after a click.

A checklist to prove it works

Create this file. It is wrong on purpose, so each tool has something to catch.

src/components/SetupCheck.vueBreaks
<script setup lang="ts">
import { ref } from "vue";

const count = ref(0);
const unused = "lint me";
</script>

<template>
  <button type="button" @click="count++">Clicked {{ count.toUpperCase() }} times</button>
</template>
  1. count.toUpperCase() is underlined in red with "Property 'toUpperCase' does not exist on type 'number'". That is the Vue extension and TypeScript working together.
  2. unused is flagged by ESLint as assigned but never used. That is the ESLint extension reading your flat config.
  3. Save. The double quotes become single quotes and the semicolons disappear. That is format on save with your .prettierrc.json.
  4. Run npx vue-tsc --build. It reports the same toUpperCase error, so the editor and the command line agree.
  5. Fix the file (show {{ count }} and delete unused), use the component in App.vue, and start npm run dev. Press Option+Shift+D and the overlay appears.
  6. In Components, select SetupCheck, change count to 5, and see the button text change.
  7. Click a component's "open in editor" icon. SetupCheck.vue opens in your editor.

If a step fails, its number tells you which piece to look at. A missing red underline is usually a TypeScript version problem (the TypeScript 7 language server is on, or VS Code is not using the workspace version); a file that does not format usually has a second formatter set as the default.

Check it stuck3 questions from the Editor and Vue DevTools quiz.
Practice now
Was this helpful?

Keep reading