cheat sheet
vue (@vue/cli)
The legacy @vue/cli command-line tool for scaffolding and serving Vue projects — deprecated in favour of create-vue + Vite, retained as reference for existing apps.
vue (@vue/cli) — Legacy Vue project scaffolder
Deprecation banner.
@vue/cli(thevuebinary) is in maintenance mode. For all new Vue 3 projects, usecreate-vue(npm create vue@latest) plus Vite. The Vue core team's recommendation. Use@vue/clionly when maintaining an existing project that already depends on it. This article exists as a reference, not a recommendation.
What it is
vue is the binary exposed by the @vue/cli npm package — the historical scaffolder, dev server, and build runner for Vue.js applications. It wraps Webpack via @vue/cli-service and offers a plugin system (@vue/cli-plugin-*), a graphical UI (vue ui), and project presets. It supports both Vue 2 and Vue 3.
The modern equivalent is create-vue (run via npm create vue@latest) + Vite. Vite has 10–100× faster dev start, smaller config surface, and tracks the rest of the modern frontend ecosystem. @vue/cli receives security fixes but no new features.
Reach for vue (legacy CLI) only when:
- Maintaining an existing
@vue/cli-scaffolded project. - A
@vue/cli-plugin-*you require has no Vite equivalent. - Bound by team / org policy to a frozen Webpack toolchain.
In all other cases, scaffold with create-vue instead.
Install
The CLI is published as @vue/cli. The vue binary becomes available on PATH after install.
npm install -g @vue/cli
Output: added @vue/cli; vue on PATH
pnpm add -g @vue/cli
Output: added @vue/cli globally
yarn global add @vue/cli
Output: added @vue/cli globally
One-off use without install:
npx @vue/cli create my-app
Output: runs the scaffolder once.
Modern replacement (recommended for new projects):
npm create vue@latest my-app
Output: runs the create-vue Vite-based scaffolder.
Verify:
vue --version
Output: prints CLI version (currently 5.x line)
Day-to-day commands
| Command | What it does |
|---|---|
vue create <name> | Scaffold a new Vue project (interactive preset). |
vue create <name> --preset default | Skip prompts; use named preset. |
vue create <name> --preset <user>/<repo> | Use a remote preset (GitHub). |
vue add <plugin> | Install a @vue/cli-plugin-* into an existing project and run its generator. |
vue invoke <plugin> | Re-run a plugin's generator (modifies source). |
vue serve [entry] | Zero-config dev server for a single .vue or .js file. |
vue build [entry] | Zero-config production build for a single entry. |
vue ui | Launch the graphical project dashboard on port 8000. |
vue inspect [options] | Print the resolved Webpack config. |
vue config | Inspect / edit global CLI config (~/.vuerc). |
vue upgrade | Upgrade @vue/cli-* deps in the current project. |
vue info | Show environment info (Node, OS, browsers) for bug reports. |
Per-project scripts (defined in package.json by the scaffold):
| Command | What it does |
|---|---|
npm run serve (or vue-cli-service serve) | Dev server (Webpack dev middleware). |
npm run build | Production build to dist/. |
npm run lint | Run ESLint via @vue/cli-plugin-eslint. |
npm run test:unit | Jest / Mocha via the unit-test plugin. |
npm run test:e2e | Cypress / Nightwatch via the e2e plugin. |
Common scenarios
Scaffold a new Vue 3 project (legacy method)
vue create my-app
Output: interactive prompt for preset. Choose Manual to pick Vue 3, TypeScript, Router, Pinia (or Vuex), ESLint, unit testing.
The resulting project is Webpack-based. For Vite-based scaffolding (recommended):
npm create vue@latest my-app
Output: Vite-based; faster dev and build.
Scaffold without prompts (CI / scripted)
vue create my-app --preset default --packageManager pnpm
Output: scaffolds using the default preset and pnpm.
For repeated use, save your own preset to ~/.vuerc after a manual scaffold — subsequent vue create runs offer it as an option.
Add a plugin to an existing project
vue add @vue/typescript
vue add @vue/pwa
vue add router
vue add vuex
Output: installs the plugin and runs its generator, which rewrites source files and package.json. Review the Git diff before committing — always run on a clean working tree.
For non-@vue/-namespaced plugins:
vue add apollo
vue add vuetify
Output: installs @vue/cli-plugin-<name> (or the community equivalent) and runs its generator.
GUI mode
vue ui
Output: opens http://localhost:8000 with the project dashboard. Useful for demos and tutorials; superseded by editor integrations for daily work.
Inspect the Webpack config
@vue/cli projects do not "eject" — you customise via vue.config.js. To see the resolved Webpack config that ncu-service generates:
vue inspect > webpack.resolved.js
vue inspect --rule vue
vue inspect --plugin html
Output: prints (or writes) the full config. Useful for debugging plugin interactions.
To customise, edit vue.config.js:
module.exports = {
publicPath: process.env.NODE_ENV === "production" ? "/my-app/" : "/",
configureWebpack: {
resolve: {
alias: { "@components": "src/components" },
},
},
chainWebpack: (config) => {
config.module
.rule("vue")
.use("vue-loader")
.tap((options) => ({ ...options, hotReload: true }));
},
};
The chainWebpack API uses webpack-chain and is @vue/cli-specific. It does NOT exist in Vite — vite.config.ts uses a different plugin model.
Production build
npm run build
Output: generates dist/ with hashed assets ready for any static host.
Deploy targets: Cloudflare Pages, Vercel, Netlify, Nginx, S3 + CloudFront, GitHub Pages. SPA history-mode routing needs a fallback to index.html for unknown paths (Pages: _redirects with /* /index.html 200).
Migrate to Vite (the recommended modern path)
The Vite migration is the most important workflow this article documents. Steps:
npm create vue@latest my-app-vitein a sibling directory. Pick the same options as your existing project.- Copy
src/,public/,index.html(with adjustments) from the old project. - Replace
vue.config.jscustomisations withvite.config.tsequivalents. - Replace
@vue/cli-plugin-*deps with their Vite-ecosystem equivalents (see the table below). - Update
package.jsonscripts:"dev": "vite","build": "vue-tsc -b && vite build","preview": "vite preview". - Run
npm test/npm run buildand fix import-path issues — Vite is stricter about extensions and aliases. - Migrate one route / feature at a time for large codebases.
Migration plugin replacements:
@vue/cli plugin | Vite-era replacement |
|---|---|
@vue/cli-plugin-babel | (handled by Vite/esbuild) |
@vue/cli-plugin-typescript | vue-tsc + Vite |
@vue/cli-plugin-eslint | eslint + eslint-plugin-vue directly |
@vue/cli-plugin-pwa | vite-plugin-pwa |
@vue/cli-plugin-router | vue-router (no plugin needed) |
@vue/cli-plugin-vuex | pinia (Vuex is deprecated) |
@vue/cli-plugin-unit-jest | vitest |
@vue/cli-plugin-unit-mocha | vitest |
@vue/cli-plugin-e2e-cypress | cypress directly |
@vue/cli-plugin-e2e-nightwatch | playwright (preferred) |
@vue/cli-service | vite |
Detailed migration guide: vuejs.org/guide/scaling-up/tooling.
Useful flags
| Flag | Purpose |
|---|---|
--preset <name> | Skip prompts; use a saved or built-in preset. |
--default | Use the default preset. |
--inlinePreset <json> | Pass preset config as JSON inline. |
--packageManager <pm> | npm, yarn, or pnpm. |
--registry <url> | npm registry override. |
--git [message] | Initialise git with optional commit message. |
--no-git | Skip git init. |
--force | Overwrite an existing target directory. |
--clone | For remote presets, use git clone instead of the npm-style fetch. |
--proxy <url> | HTTP proxy for the scaffold's downloads. |
--bare | Scaffold without the demo welcome page. |
--skipGetStarted | Suppress the "Get Started" output. |
For vue-cli-service (per-project, via npm run):
| Flag | Purpose |
|---|---|
--mode <mode> | development / production / test / custom. |
--no-clean | Don't clear dist/ before build. |
--report | Emit a Webpack bundle-analyser report. |
--inspect [port] | Run the dev server with Node Inspector. |
--copy | Copy the dev URL to clipboard. |
--host / --port | Override dev-server host/port. |
--watch | Build in watch mode. |
Configuration
vue.config.js (CommonJS) at the project root configures @vue/cli-service:
const { defineConfig } = require("@vue/cli-service");
module.exports = defineConfig({
publicPath: process.env.NODE_ENV === "production" ? "/my-app/" : "/",
outputDir: "dist",
productionSourceMap: false,
lintOnSave: process.env.NODE_ENV !== "production",
devServer: {
port: 8080,
proxy: {
"/api": {
target: "http://localhost:3000",
changeOrigin: true,
pathRewrite: { "^/api": "" },
},
},
},
chainWebpack: (config) => {
config.plugin("html").tap((args) => {
args[0].title = "My App";
return args;
});
},
pluginOptions: {
// plugin-specific config
},
});
Per-environment files: .env, .env.local, .env.development, .env.production. Variables must be prefixed VUE_APP_ to be exposed to client code.
Global CLI config: ~/.vuerc (saved presets, package-manager default, registry).
Common pitfalls
- You picked the wrong tool. Many tutorials still say
vue create. They're outdated. For new projects usenpm create vue@latest(thecreate-vuescaffold). vue.config.js≠vite.config.ts. Migrating to Vite means re-authoring config from scratch. ThechainWebpackAPI doesn't translate.- Webpack 5 + Node 17+ OpenSSL. Older
@vue/cliprojects on newer Node fail withERR_OSSL_EVP_UNSUPPORTED. AddNODE_OPTIONS=--openssl-legacy-provideror upgrade to@vue/cli@5. ERR_REQUIRE_ESM— A transitive dep went ESM-only (e.g.chalk@5,node-fetch@3). Pin those deps to their last CJS-compatible major, or migrate to Vite.vue add <plugin>modifies source. Always run on a clean Git working tree so you can review the diff. Some plugin generators rewrite entry points and break customisations.VUE_APP_*prefix required for env vars. Without it, the variable is dropped at build time. Easy to miss when porting from another framework.publicPathmis-set in sub-path deploys. A subdirectory deploy (e.g.example.com/my-app/) needspublicPath: "/my-app/". Forgetting it breaks all hashed asset URLs.vue uiexposes a local server. Port 8000 by default. Don't run on a multi-user machine.- SPA history-mode routes 404 in production. Configure the host to fall back to
index.htmlfor unknown paths. - Vue 2 is end-of-life. Vue 2.7 reached EOL in late 2023. Either pay for HeroDevs' extended support, or migrate to Vue 3 + create-vue + Vite.
See also
- Packages-npm: @vue/cli — package-level reference + deprecation context
- JavaScript: vite — the modern Vue build tool
- Packages-npm: vite — package-level reference for Vite
- JavaScript: npm —
npm createis howcreate-vueis invoked