CodeVetter
← All unpacks
CodeVetter · Repo Unpack evidence

vuejs/core

Scanned commit 4ab865a848 dated 2026-09-18 — last upstream commit. Generated by codevetter 1.12.0 on 2026-09-22.

github.com/vuejs/core ↗ · 696 files · 5.5 MB

vuejs/core Getting Started Please follow the documentation at vuejs.org!

Deep analysis by claude-opus-5 via the claude CLI on 2026-09-22 (436s) — every claim below links to its cited source files.

Overview

This is the vuejs/core monorepo at v3.5.43 — the source of the `vue` npm package and its ten sibling `@vue/*` packages, split cleanly into a compiler half (compiler-core → compiler-dom → compiler-sfc/compiler-ssr) and a runtime half (reactivity → runtime-core → runtime-dom/server-renderer), glued by `@vue/shared`. The distinctive engineering shape is compile-time configurability: every package is built by a single `rollup.config.js` driven by `scripts/build.js` into up to seven output formats, with `__DEV__`/`__BROWSER__`/`__FEATURE_*`/`__COMPAT__` flags statically replaced so that dev warnings, the Options API, Suspense, and the Vue-2 compat layer all tree-shake away. It is written for framework maintainers and ecosystem tool authors rather than app developers: the public API surface is small, but the internal surface (renderer internals object, `createRenderer` for custom platforms, compiler `nodeTransforms`/`directiveTransforms`) is explicitly designed as an extension substrate. Two private packages — `sfc-playground` and `template-explorer` — are live-deployed dev tools that consume the built artifacts of the very repo that builds them.

System map

A pnpm workspace (`packages/*` + `packages-private/*`) of eleven published-or-private packages with a strict compiler/runtime separation enforced by lint rules. There is no server, database, or persistent storage layer — the "storage" is the filesystem (dist bundles) plus in-memory LRU caches in the compiler. Builds go through `scripts/build.js` → `rollup.config.js`, which fans one package out into esm-bundler/esm-browser/cjs/global/runtime variants; types are stitched separately via `tsc -p tsconfig.build.json --noCheck && rollup -c rollup.dts.config.js`. Tests run under Vitest with five named projects (unit, unit-gc, unit-jsdom, e2e, e2e-browser). Deployment is npm publish from a tag-triggered GitHub Actions workflow, plus continuous pre-release publishing via pkg-pr-new on every push.

All 13 system map claims →

Feature catalog

There are no routes or screens in the product sense — the user-facing surface is (a) the public JS API exported from `@vue/runtime-core`/`@vue/runtime-dom`, (b) the compiler APIs consumed by vite-plugin-vue/vue-loader, (c) SSR render functions, (d) the `nr <script>` developer command surface in package.json, and (e) two deployed browser tools. Built-in components (Teleport, Suspense, KeepAlive, BaseTransition, Transition, TransitionGroup) and built-in directives (v-model, v-show, v-on modifiers) are shipped as first-class features handled specially in both the compiler and the renderer. Custom elements and lazy-hydration strategies are the newer feature surfaces.

All 13 feature catalog claims →

Data flow

Two largely independent pipelines meet at the component instance. Compile-time: template/SFC source string → tokenizer/parser → AST → transform passes (which mutate the AST and register runtime helpers) → codegen → render-function source. Runtime: props/slots enter via vnodes, reactive state is owned by `Dep` objects linked to `Subscriber`s, changes call `trigger()` which notifies effects, effects are batched into the scheduler queue, and the flush drives `patch()` which writes to the host platform through the injected `RendererOptions`. Output boundaries are exactly three: DOM mutations via `nodeOps`/`patchProp`, an SSR string/stream buffer, and generated JS source text.

All 13 data flow claims →

Behavior traces

Three flows carry most of the system's weight: browser app startup, a reactive state change producing a re-render, and SFC compilation as invoked by a bundler plugin. A fourth, hydration, forks off startup at `createSSRApp`. The call chains below were read in order through runtime-dom → apiCreateApp → renderer → component → scheduler.

All 13 behavior traces claims →

Testing signals

Vitest is the only test runner, with 196 spec files collocated in per-package `__tests__` directories and five projects configured in `vitest.config.ts` to isolate environment needs. Coverage is v8-based over `packages/*/src/**` with an explicit exclusion list that documents what is deliberately not unit-tested. Type correctness is tested separately by compiling `packages-private/dts-test` against generated `.d.ts` files, and treeshaking is asserted by a bespoke script. There is no mutation testing, no snapshot-free contract layer, and no coverage threshold gate in CI.

All 13 testing signals claims →

Risk map

The security surface is narrow but sharp: three code paths build render functions with `new Function`, two paths assign `innerHTML`, and the SFC compiler reads arbitrary files off disk and `require`s user-supplied preprocessors. Structurally, the biggest blast radius is `renderer.ts` (2670 lines, the single implementation behind every platform) and the `__COMPAT__` layer, which threads conditionals through core runtime code that most contributors never exercise. CI hygiene is unusually strong (pinned action SHAs, `persist-credentials: false`, org-membership gating on the ecosystem-ci trigger), so the residual risks are code-level rather than pipeline-level.

All 14 risk map claims →

Extension points

Extensibility is designed in at four levels. Platform level: `createRenderer(options)` lets anyone build a custom renderer from the same core — `runtime-test` is the in-repo proof. Compile level: `nodeTransforms`/`directiveTransforms` are concatenated after the built-in presets, and compiler-dom/compiler-ssr are themselves just different preset compositions. App level: `app.use`/`app.component`/`app.directive`/`app.mixin` plus `app.config` hooks. Type level: declaration merging into `@vue/runtime-core` interfaces. Adding a package means adding a directory with a `buildOptions` block — `scripts/aliases.js` and `scripts/build.js` discover it automatically.

All 13 extension points claims →

Contributor handoff

Read the contributing guide's Project Structure and Package Dependencies sections before touching anything — the import rules there are enforced by both eslint and the release process. Expect ES2016-target lint restrictions that will reject idiomatic modern TypeScript, and expect every dev-only behaviour to be guarded by a `__DEV__` flag that must tree-shake cleanly. The fastest verification loop is `pnpm test-unit <package>`; the slowest and most CI-relevant are `pnpm check`, `pnpm test-dts` and `node scripts/verify-treeshaking.js`. Never reach across packages with relative paths, and never add a runtime import to a compiler package.

All 14 contributor handoff claims →

Languages

LanguageFilesShare of source
TypeScript48991%
JavaScript367%
Markdown31docs/config
JSON30docs/config
HTML25docs/config
YAML12docs/config
Vue112%
CSS1docs/config

Start reading here

Probable source entrypoint: packages/ — inferred from the directory tree and manifest, not the upstream docs.

Source roots

packages/ (569 files)

Source layout — packages/

PathFiles
packages/compiler-core/69
packages/compiler-sfc/69
packages/runtime-dom/37
packages/vue/46
packages/vue-compat/22

Repository structure

Top-level pathFiles
packages/569
packages-private/72
.github/17
scripts/12
changelogs/5
.well-known/1

Docs found: README.md

Package

package.json — v3.5.43, 52 declared dependencies.

@babel/parser@babel/types@rollup/plugin-alias@rollup/plugin-commonjs@rollup/plugin-json@rollup/plugin-node-resolve@rollup/plugin-replace@swc/core@types/hash-sum@types/node@types/semver@types/serve-handler

CI & config entrypoints

Structural health signals

Average score 7.1/10 across 96 analyzed source files; 23 hotspots surfaced.

These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.

Recent history