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 (the vue binary) is in maintenance mode. For all new Vue 3 projects, use create-vue (npm create vue@latest) plus Vite. The Vue core team's recommendation. Use @vue/cli only 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.

bash
npm install -g @vue/cli

Output: added @vue/cli; vue on PATH

bash
pnpm add -g @vue/cli

Output: added @vue/cli globally

bash
yarn global add @vue/cli

Output: added @vue/cli globally

One-off use without install:

bash
npx @vue/cli create my-app

Output: runs the scaffolder once.

Modern replacement (recommended for new projects):

bash
npm create vue@latest my-app

Output: runs the create-vue Vite-based scaffolder.

Verify:

bash
vue --version

Output: prints CLI version (currently 5.x line)

Day-to-day commands

CommandWhat it does
vue create <name>Scaffold a new Vue project (interactive preset).
vue create <name> --preset defaultSkip 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 uiLaunch the graphical project dashboard on port 8000.
vue inspect [options]Print the resolved Webpack config.
vue configInspect / edit global CLI config (~/.vuerc).
vue upgradeUpgrade @vue/cli-* deps in the current project.
vue infoShow environment info (Node, OS, browsers) for bug reports.

Per-project scripts (defined in package.json by the scaffold):

CommandWhat it does
npm run serve (or vue-cli-service serve)Dev server (Webpack dev middleware).
npm run buildProduction build to dist/.
npm run lintRun ESLint via @vue/cli-plugin-eslint.
npm run test:unitJest / Mocha via the unit-test plugin.
npm run test:e2eCypress / Nightwatch via the e2e plugin.

Common scenarios

Scaffold a new Vue 3 project (legacy method)

bash
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):

bash
npm create vue@latest my-app

Output: Vite-based; faster dev and build.

Scaffold without prompts (CI / scripted)

bash
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

bash
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:

bash
vue add apollo
vue add vuetify

Output: installs @vue/cli-plugin-<name> (or the community equivalent) and runs its generator.

GUI mode

bash
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:

bash
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:

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

bash
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).

The Vite migration is the most important workflow this article documents. Steps:

  1. npm create vue@latest my-app-vite in a sibling directory. Pick the same options as your existing project.
  2. Copy src/, public/, index.html (with adjustments) from the old project.
  3. Replace vue.config.js customisations with vite.config.ts equivalents.
  4. Replace @vue/cli-plugin-* deps with their Vite-ecosystem equivalents (see the table below).
  5. Update package.json scripts: "dev": "vite", "build": "vue-tsc -b && vite build", "preview": "vite preview".
  6. Run npm test / npm run build and fix import-path issues — Vite is stricter about extensions and aliases.
  7. Migrate one route / feature at a time for large codebases.

Migration plugin replacements:

@vue/cli pluginVite-era replacement
@vue/cli-plugin-babel(handled by Vite/esbuild)
@vue/cli-plugin-typescriptvue-tsc + Vite
@vue/cli-plugin-eslinteslint + eslint-plugin-vue directly
@vue/cli-plugin-pwavite-plugin-pwa
@vue/cli-plugin-routervue-router (no plugin needed)
@vue/cli-plugin-vuexpinia (Vuex is deprecated)
@vue/cli-plugin-unit-jestvitest
@vue/cli-plugin-unit-mochavitest
@vue/cli-plugin-e2e-cypresscypress directly
@vue/cli-plugin-e2e-nightwatchplaywright (preferred)
@vue/cli-servicevite

Detailed migration guide: vuejs.org/guide/scaling-up/tooling.

Useful flags

FlagPurpose
--preset <name>Skip prompts; use a saved or built-in preset.
--defaultUse 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-gitSkip git init.
--forceOverwrite an existing target directory.
--cloneFor remote presets, use git clone instead of the npm-style fetch.
--proxy <url>HTTP proxy for the scaffold's downloads.
--bareScaffold without the demo welcome page.
--skipGetStartedSuppress the "Get Started" output.

For vue-cli-service (per-project, via npm run):

FlagPurpose
--mode <mode>development / production / test / custom.
--no-cleanDon't clear dist/ before build.
--reportEmit a Webpack bundle-analyser report.
--inspect [port]Run the dev server with Node Inspector.
--copyCopy the dev URL to clipboard.
--host / --portOverride dev-server host/port.
--watchBuild in watch mode.

Configuration

vue.config.js (CommonJS) at the project root configures @vue/cli-service:

js
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

  1. You picked the wrong tool. Many tutorials still say vue create. They're outdated. For new projects use npm create vue@latest (the create-vue scaffold).
  2. vue.config.jsvite.config.ts. Migrating to Vite means re-authoring config from scratch. The chainWebpack API doesn't translate.
  3. Webpack 5 + Node 17+ OpenSSL. Older @vue/cli projects on newer Node fail with ERR_OSSL_EVP_UNSUPPORTED. Add NODE_OPTIONS=--openssl-legacy-provider or upgrade to @vue/cli@5.
  4. 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.
  5. 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.
  6. VUE_APP_* prefix required for env vars. Without it, the variable is dropped at build time. Easy to miss when porting from another framework.
  7. publicPath mis-set in sub-path deploys. A subdirectory deploy (e.g. example.com/my-app/) needs publicPath: "/my-app/". Forgetting it breaks all hashed asset URLs.
  8. vue ui exposes a local server. Port 8000 by default. Don't run on a multi-user machine.
  9. SPA history-mode routes 404 in production. Configure the host to fall back to index.html for unknown paths.
  10. 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