RepoPilotOpen in app →

vuejs/vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core

WAIT

Stale — last commit 2y ago

  • 5 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • Stale — last commit 2y ago
  • Small team — 5 top contributors
  • Single-maintainer risk — top contributor 81% of commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Embed this verdict

[![RepoPilot: WAIT](https://repopilot.app/api/badge/vuejs/vue)](https://repopilot.app/r/vuejs/vue)

Paste into your README — the badge live-updates from the latest cached analysis.

Onboarding doc

Onboarding: vuejs/vue

Generated by RepoPilot · 2026-05-04 · Source

Verdict

WAIT — Stale — last commit 2y ago

  • 5 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Stale — last commit 2y ago
  • ⚠ Small team — 5 top contributors
  • ⚠ Single-maintainer risk — top contributor 81% of commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

TL;DR

This is the official source repository for Vue 2, a progressive JavaScript framework for building reactive user interfaces via a component-based model, virtual DOM diffing, and a template compiler. It ships multiple build artifacts under dist/ (vue.common.js, vue.runtime.mjs, etc.) targeting different module systems (CJS, ESM). As of December 31, 2023, it is officially End of Life and receives no new features, bug fixes, or security patches. The repo is a single-package layout: compiled distribution files live in dist/ (vue.common.js, vue.runtime.common.js, vue.runtime.mjs), the SFC compiler tooling is isolated under compiler-sfc/ with its own package.json and dual CJS/ESM entry points (index.js, index.mjs). Source TypeScript lives in src/ (not listed in top-60 but the 1.85 MB TypeScript share confirms it), and runnable benchmarks and classic examples are under benchmarks/ and examples/classic/.

Who it's for

Frontend developers maintaining legacy Vue 2 applications who need to understand internals, submit backport patches, or fork the codebase. Also relevant to library authors who build Vue 2-compatible plugins and need to understand the reactivity system, compiler pipeline, or SFC tooling exposed via compiler-sfc/.

Maturity & risk

Vue 2 is a battle-hardened, production-grade framework used by millions of projects since 2016, with comprehensive CI via GitHub Actions (.github/workflows/ci.yml) and broad test coverage. However, it officially reached End of Life on 2023-12-31, meaning no further commits, fixes, or releases are planned from the core team. It is production-ready for existing projects but must not be chosen for new work.

The primary risk is the EOL status — no security vulnerabilities will be patched by the Vue core team, which is a compliance and security concern for regulated environments (the README explicitly points to Vue 2 NES from HeroDevs as a commercial support option). The codebase has no single-maintainer risk historically but is now effectively frozen; any fork or patch must be self-maintained. Dependencies in compiler-sfc/package.json are also frozen at their last-released versions.

Active areas of work

Nothing active — the repository is frozen post-EOL (December 31, 2023). The GitHub Actions workflows (.github/workflows/ci.yml, release-tag.yml) remain in place but no new releases or PRs are being merged by the core team. The CHANGELOG.md reflects the last release history.

Get running

git clone https://github.com/vuejs/vue.git cd vue npm install npm run build

To run a specific benchmark locally:

open benchmarks/big-table/index.html

Daily commands: npm run dev # watch mode, builds vue.js in dist/ npm run build # full production build of all dist/ artifacts npm run test # run unit + e2e test suite npm run bench # not a standard script; open benchmarks/*/index.html directly in browser

Map of the codebase

  • dist/vue.common.js — The compiled full Vue 2 runtime+compiler bundle — the canonical output that ships to consumers and reveals the complete architecture including observer, vdom, and compiler in one file.
  • dist/vue.runtime.common.js — The runtime-only build (no template compiler) used by webpack/rollup setups with vue-loader; understanding the split between this and vue.common.js is essential for build optimization.
  • packages/compiler-sfc/src/index.ts — Public API surface for the Single File Component compiler package — the entry point that re-exports parse, compileTemplate, compileScript, and compileStyle used by all tooling.
  • packages/compiler-sfc/src/parse.ts — Parses .vue SFC files into descriptor blocks (template/script/style); every build tool integration starts here and its output shape drives all downstream compilation.
  • packages/compiler-sfc/src/compileScript.ts — Handles <script setup> compilation including bindings analysis, macro transforms (defineProps, defineEmits), and is by far the most complex file in the compiler-sfc package.
  • packages/compiler-sfc/src/compileTemplate.ts — Transforms the <template> block into a render function, delegating to the template compiler with scoped-id injection and asset URL rewriting.
  • packages/compiler-sfc/src/compileStyle.ts — Processes <style> blocks through CSS preprocessors and PostCSS, applying scoped CSS transformations and CSS variable injection critical to Vue's style encapsulation.

How to make changes

Add a new CSS preprocessor support

  1. Add a new preprocessor adapter function (following the SassStylePreprocessor/LessStylePreprocessor pattern) that implements the StylePreprocessor interface (packages/compiler-sfc/src/stylePreprocessors.ts)
  2. Register the new preprocessor in the preprocessors map so compileStyle can resolve it by lang attribute value (packages/compiler-sfc/src/stylePreprocessors.ts)
  3. Export any new public types from the package index if the preprocessor introduces new options (packages/compiler-sfc/src/index.ts)

Add a new PostCSS plugin to the scoped style pipeline

  1. Create a new PostCSS plugin file in the stylePlugins directory following the pattern of scoped.ts (export a function returning a PostCSS plugin object) (packages/compiler-sfc/src/stylePlugins/scoped.ts)
  2. Import and apply the new plugin in the compileStyle pipeline, conditional on the appropriate SFCStyleCompileOptions flag (packages/compiler-sfc/src/compileStyle.ts)
  3. Add the controlling option to the SFCStyleCompileOptions type and export it (packages/compiler-sfc/src/index.ts)

Add a new <script setup> macro transform

  1. Add macro detection in the processDefineXxx pattern — find the call expression in the script's AST and extract its arguments (packages/compiler-sfc/src/compileScript.ts)
  2. Add any required Babel AST utilities needed for the macro's argument parsing (packages/compiler-sfc/src/babelUtils.ts)
  3. Export the new macro's type signature and any related interfaces from the public index (packages/compiler-sfc/src/index.ts)

Add a new template compiler transform module (e.g. custom attribute rewriting)

  1. Create a new module file in templateCompilerModules/ implementing the ASTModuleTransform interface with transformNode and/or postTransformNode hooks (packages/compiler-sfc/src/templateCompilerModules/assetUrl.ts)
  2. Import the new module and add it to the modules array passed to the template compiler options in compileTemplate (packages/compiler-sfc/src/compileTemplate.ts)
  3. Export any new option types the module introduces through the package public API (packages/compiler-sfc/src/index.ts)

Why these technologies

  • TypeScript (compiler-sfc package) — Provides type-safe AST manipulation and strong interfaces for the SFCDescriptor and compile result shapes that tooling authors depend on.
  • Babel (@babel/parser, @babel/traverse) — Used in compileScript.ts for full JS/TS AST parsing needed to implement <script setup> macro detection and binding analysis, which regex cannot handle reliably.
  • PostCSS — Provides a stable, pluggable CSS AST pipeline enabling scoped CSS attribute injection and CSS variable extraction without writing a custom CSS parser.
  • Rollup (build tool for dist/) — Produces clean, tree-shakeable ESM and CJS bundles (vue.runtime.mjs, vue.common.js) with precise control over what enters the runtime bundle.
  • Vue 2 Options API (runtime core) — The original reactive system based on Object.defineProperty was chosen for broad browser compatibility (IE11) without requiring Proxy support.

Trade-offs already made

  • Split runtime-only vs full (runtime+compiler) builds
    • Why: Allows production apps using vue-loader to ship without the 30KB template compiler since templates are pre-compiled at build time.
    • Consequence: Two separate bundles (vue.common.js, vue.runtime.common.js) must be maintained; build tool

Traps & gotchas

The Object.defineProperty-based reactivity system cannot detect property addition/deletion on plain objects or index-based mutations on arrays — these are fundamental Vue 2 limitations (not bugs), and any contributor must internalize them before touching src/core/observer/. The compiler-sfc/ directory is a separate installable package with its own dependency versions; changes there do not automatically sync with the root package. api-extractor.tsconfig.json uses a separate TS config from the main build, so type errors may appear in one but not the other.

Architecture

Concepts to learn

  • Object.defineProperty-based Reactivity — Vue 2's entire reactive data system is built on Object.defineProperty getters/setters to track dependencies — understanding this explains why array mutations and property additions require special APIs like Vue.set().
  • Virtual DOM and VNode Tree Diffing — Vue 2 renders components to an in-memory VNode tree and uses a patch algorithm to diff old and new trees before touching the real DOM — this is the core of the rendering pipeline in dist/vue.common.js.
  • Template Compiler Pipeline — Vue 2 templates are parsed into an AST, optimized (static node hoisting), then codegen'd into render function strings — all three phases exist in src/compiler/ and are exposed via compiler-sfc/.
  • Single-File Components (SFC) — The .vue file format combining template, script, and style blocks is compiled by the compiler-sfc/ package in this repo — understanding the block parsing and scoped CSS transform is essential for tooling contributors.
  • Dependency Tracking via Watcher/Dep Graph — Vue 2 uses a Dep class (dependency) and Watcher class to form a push-based reactive graph — each reactive property holds a Dep, and each computed/watch creates a Watcher that subscribes to Deps during evaluation.
  • Async Update Queue (nextTick) — Vue 2 batches watcher re-runs into a microtask queue flushed via Promise/MutationObserver/setTimeout fallback — this is why DOM updates are not synchronous and why Vue.nextTick() exists.
  • API Extractor for TypeScript Public Surface — api-extractor.json controls which TypeScript symbols are included in the rolled-up index.d.ts — contributors adding new exported types must understand this tool to avoid accidentally leaking internal types.

Related repos

  • vuejs/core — The actively maintained Vue 3 repository — the direct successor to this codebase and the migration target for all Vue 2 projects.
  • vuejs/vue-loader — The webpack loader that consumes compiler-sfc/ to transform .vue single-file components — tightly coupled to this repo's SFC compiler output.
  • vuejs/vue-router — The official Vue 2-compatible router, commonly used alongside this framework and sharing its reactivity model.
  • vuejs/vuex — The official Vue 2 state management library, built on Vue 2's reactivity system defined in this repo.
  • meteorlxy/vue-2-3 — A compatibility shim project that demonstrates the API differences between Vue 2 (this repo) and Vue 3, useful as a migration reference.

PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add missing benchmark index/entry page linking all benchmarks in benchmarks/

The benchmarks/ directory contains six separate benchmark scenarios (big-table, dbmon, reorder-list, ssr, svg, uptime) but there is no top-level index.html or README.md to explain what each benchmark measures, how to run them locally, or how to interpret results. Since Vue 2 is now in EOL maintenance mode, having well-documented benchmarks is valuable for users comparing Vue 2 vs Vue 3 performance when deciding whether to migrate. This is a concrete, bounded contribution that directly improves developer experience.

  • [ ] Create benchmarks/README.md describing each benchmark subdirectory: big-table, dbmon, reorder-list, ssr, svg, uptime
  • [ ] Document how to serve each benchmark locally (e.g. using npx serve or a simple http-server command) referencing benchmarks/ssr/README.md as an existing example to match in style
  • [ ] Add a benchmarks/index.html that links to each benchmark's index.html for easy browser-based navigation
  • [ ] In benchmarks/ssr/README.md, verify and update any outdated Node version or dependency instructions to match the current repo
  • [ ] Open PR targeting the main branch with only the benchmarks/ directory changes

Add missing TypeScript type definitions for compiler-sfc package (compiler-sfc/index.d.ts)

The compiler-sfc/ directory ships compiler-sfc/index.d.ts, compiler-sfc/index.js, and compiler-sfc/index.mjs, but the package.json snippet shows types pointing to index.d.ts. Given that Vue 2 is EOL and many users are on this version for the long term, having accurate and complete type declarations in compiler-sfc/index.d.ts ensures IDE tooling and TypeScript projects remain usable without upstream updates. A contributor can audit the exported API surface of compiler-sfc/index.js and ensure every export has a corresponding TypeScript declaration.

  • [ ] Audit compiler-sfc/index.js and compiler-sfc/index.mjs to enumerate all exported functions, classes, and constants
  • [ ] Open compiler-sfc/index.d.ts and cross-check each export against the TypeScript declarations present
  • [ ] Add missing or incorrect type signatures for any undeclared exports, using JSDoc comments in the .js files as a reference
  • [ ] Run the api-extractor tool (api-extractor.json and api-extractor.tsconfig.json are already present in the repo root) to validate the updated declarations
  • [ ] Add a brief note in compiler-sfc/package.json under a 'sideEffects' or 'exports' field if missing, to improve bundler compatibility

Migrate classic examples to use ES modules and remove inline scripts (examples/classic/)

The examples/classic/ subdirectories (commits, elastic-header, firebase, grid, markdown, modal, move-animations, select2) each contain index.html files that almost certainly load Vue and app logic via CDN script tags and inline or separate non-module JS files (e.g. examples/classic/commits/app.js, examples/classic/grid/grid.js, examples/classic/firebase/app.js). Modernizing these to use native ES module imports (type='module') makes them runnable directly in modern browsers without a build step and improves readability for contributors learning Vue 2 internals. It also demonstrates best practices for users who must stay on Vue 2.

  • [ ] Audit each index.html in examples/classic/ (commits, elastic-header, firebase, grid, markdown, modal, move-animations, select2) to identify CDN script tags and inline scripts
  • [ ] Convert examples/classic/commits/app.js and examples/classic/grid/grid.js to use ES module syntax (import/export) and update their corresponding index.html files to use <script type='module'>
  • [ ] Replace any CDN Vue 2 script tag with an importmap or direct ES module CDN URL (e

Good first issues

  1. Add missing JSDoc comments to the public methods in compiler-sfc/index.d.ts — many exported functions lack parameter and return type descriptions. 2. The benchmarks/ssr/ directory has a README.md stub but renderToStream.js and renderToString.js lack inline comments explaining the streaming chunk algorithm — documenting these would help SSR contributors. 3. examples/classic/ only covers commits and elastic-header; adding a classic TodoMVC example with v-model, computed properties, and watchers would provide a canonical reference for Vue 2 options API patterns.

Top contributors

Recent commits

  • 9e88707 — chore: fix spelling mistakes (#13216) (Moriango)
  • 73486cb — chore: fix link broken (#13192) (xiaoxianBoy)
  • e428d89 — chore: browser compatibility table link (#13187) (serious-angel)
  • bed04a7 — chore: update issue form [ci skip] (yyx990803)
  • 0191d50 — chore: eol readme (#13142) (yyx990803)
  • cdcc4f0 — chore: release name for 2.7.16 [ci skip] (yyx990803)
  • 13f4e7d — release: v2.7.16 (yyx990803)
  • 56ce7f8 — fix(lifecycle): esnure component effect scopes are disconnected (yyx990803)
  • 305e4ae — release: v2.7.16-beta.2 (yyx990803)
  • 3e1037e — chore: bump vitest to 1.0.4 (yyx990803)

Security observations

  • Critical · End-of-Life Software — No Security Patches — Entire repository / package.json. Vue 2 officially reached End of Life on December 31, 2023. The repository is no longer maintained, meaning any newly discovered security vulnerabilities (XSS, prototype pollution, ReDoS, etc.) in the framework itself or its dependencies will never receive official patches. Applications still running Vue 2 are permanently exposed to any future CVEs. Fix: Migrate to Vue 3 (vuejs/core). If migration is not feasible, evaluate a commercial long-term support option such as Vue 2 NES (HeroDevs) which provides security patches for EOL Vue 2.
  • High · Potential XSS via v-html / innerHTML Usage — dist/vue.common.js, dist/vue.runtime.common.js, compiler-sfc/. Vue 2 provides the v-html directive and the underlying innerHTML rendering path which, when bound to user-controlled or external data, creates a reflected/stored XSS vector. Static analysis of the repository reveals template compilation paths (dist/vue.common.js, compiler-sfc/) that ultimately emit raw innerHTML. Any application using v-html without sanitisation is vulnerable. Because the framework is EOL, no framework-level mitigations will be added. Fix: Audit all usages of v-html across consuming applications. Never bind unsanitised user input to v-html. Use a well-maintained HTML sanitiser (e.g., DOMPurify) before passing content to v-html.
  • High · Prototype Pollution Risk in Reactive System — dist/vue.common.js, dist/vue.runtime.common.js. Vue 2's reactivity system uses property enumeration and object merging utilities (e.g., extend, merge options) that have historically been susceptible to prototype pollution (CVE-2022-25869 and related advisories). Because the project is EOL, future variants of this class of vulnerability will not be patched. Fix: Freeze Object.prototype where feasible (Object.freeze(Object.prototype)), validate and sanitise all data that flows into Vue component options or reactive data objects, and consider migrating to Vue 3 which has a redesigned reactivity system.
  • High · Uncontrolled External Resource Loading in Example Pages — examples/classic/commits/index.html, examples/classic/firebase/index.html, examples/classic/markdown/index.html, examples/classic/modal/index.html, examples/composition/*.html. Several example HTML files (examples/classic/commits/index.html, examples/classic/firebase/index.html, examples/classic/markdown/index.html, etc.) load scripts and styles from external CDNs without Subresource Integrity (SRI) hashes. A compromised CDN could serve malicious code to any user who opens these pages. Fix: Add integrity and crossorigin attributes to all external <script> and <link> tags. Generate SRI hashes with tools such as srihash.org or the Webpack/Vite SRI plugin. Consider self-hosting dependencies.
  • High · Firebase API Keys Potentially Exposed in Example Code — examples/classic/firebase/app.js, examples/classic/firebase/index.html. examples/classic/firebase/ contains app.js and index.html that appear to configure a Firebase connection. If real API keys or project identifiers were committed (a common mistake in demo/example code), they could be abused to access or modify Firebase data. Fix: Audit the Firebase example files for hardcoded API keys, project IDs, or other credentials. Replace any real credentials with clearly fake placeholders, add the file pattern to .gitignore for consuming projects, and use environment variables or a secrets manager for real credentials.
  • Medium · Missing Content Security Policy (CSP) in Example/Benchmark Pages — benchmarks/, examples/. All benchmark and example HTML pages (benchmarks/big-table/index.html, benchmarks/dbmon/index.html, benchmarks/ssr/, examples/**/.html) lack a Content-Security-Policy meta tag or HTTP header. This leaves the pages open to XSS, clickjacking, and data injection attacks if they were ever served over HTTP. Fix: Add a <meta http-equiv="Content-Security-Policy"> tag with a restrictive policy to all HTML pages. For production deployments, deliver CSP as an HTTP response header and use nonces or hashes for inline scripts.

LLM-derived; treat as a starting point, not a security audit.

Where to read next


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

WAIT · vuejs/vue — RepoPilot Verdict