Open-Source Wikis

/

Vue.js

/

How to contribute

/

Debugging

vuejs/core

Debugging

This page collects the recipes that make iterating on Vue's internals fast.

Run the SFC Playground locally

pnpm dev-sfc starts the Single-File Component playground from packages-private/sfc-playground against your local source. Any change to compiler-sfc, runtime-core, etc. shows up after a refresh.

pnpm dev-sfc
# → vite dev server, usually http://localhost:5173

This is the fastest reproduction loop for SFC bugs. Paste the user-supplied repro into the editor and step into Vue source from the browser devtools (source maps are enabled in dev builds).

Inspect compiled template output

pnpm dev-compiler boots packages-private/template-explorer at http://localhost:3000. The left pane is a template; the right pane is the AST and generated render function. This is the right tool when:

  • Debugging a compiler-core transform.
  • Verifying a cacheStatic/static-hoisting decision.
  • Understanding what patch flags the compiler emits for a particular construct.

The explorer respects URL hash params for the source so you can paste links.

Step through the runtime in dev mode

pnpm dev produces unminified, sourcemap-enabled bundles in each package's dist/:

# rebuild whenever runtime-core changes
pnpm dev runtime-core

# or watch the full vue.global.js
pnpm dev

Load the resulting file from an HTML page and you can place breakpoints in the original .ts source via Chrome devtools.

For ESM-bundler scenarios, use pnpm dev-esm. That builds vue/dist/vue-runtime.esm-bundler.js with all deps inlined via esbuild — useful when reproducing a real-world bundler issue against a globally linked checkout.

Use runtime-test for renderer/scheduler bugs

packages/runtime-test ships an in-memory renderer with nodeOps.ts (~5KB) and a serialize.ts helper. It is the easiest way to write a focused test for renderer or scheduler logic without DOM noise. The whole test suite for the renderer relies on it; mimic the patterns you find in packages/runtime-core/__tests__/.

Inject a custom error/warn handler

runtime-core's warning system flows through packages/runtime-core/src/warning.ts and the error handler in packages/runtime-core/src/errorHandling.ts. In dev builds:

  • Set app.config.errorHandler to capture all uncaught errors with the instance and info strings (info is keyed in ErrorTypeStrings).
  • Set app.config.warnHandler to intercept warnings before they hit the console.
  • Use app.config.performance = true to add performance.mark entries for component lifecycle phases (see packages/runtime-core/src/profiling.ts).

Devtools hook

Vue exposes __VUE_DEVTOOLS_GLOBAL_HOOK__ via packages/runtime-core/src/devtools.ts. The browser devtools extension hooks here. In a custom build, set __VUE_PROD_DEVTOOLS__ to true to keep the hook in production for diagnostic purposes.

Reactivity tracing

packages/reactivity/src/effect.ts accepts onTrack and onTrigger debugger hooks on ReactiveEffect. Public APIs that wrap effects (watch, watchEffect, computed, defineComponent via onRenderTracked/onRenderTriggered) all forward these:

onRenderTriggered((event) => {
  console.log('rerender because of', event.key, event.target, event.type);
});

This is invaluable when a component re-renders unexpectedly.

Common things to grep for

  • Bug filed against a directive? Search packages/compiler-core/src/transforms/v<Name>.ts and packages/runtime-dom/src/directives/v<Name>.ts.
  • Bug filed against a built-in component? See packages/runtime-core/src/components/<Name>.ts.
  • Bug filed against a Vue 2 compat behavior? See packages/runtime-core/src/compat/ (gated by __COMPAT__).
  • Mystery warning text? git grep "the warning string" will land you on the call site, which is always wrapped in an if (__DEV__) branch.

Performance and size

  • pnpm bench runs the reactivity microbenchmarks under packages/reactivity/__benchmarks__/. pnpm bench-compare re-runs against the saved JSON baseline.
  • pnpm size builds the size-tracked bundles and prints the gzip and brotli sizes via scripts/size-report.js. The CI workflow .github/workflows/size-report.yml posts the delta to PRs.

If a change inflates the runtime bundle by more than a few hundred bytes, the PR will need justification. Compiler-side code is held to a looser size budget because it doesn't ship to the client.

When you are stuck

The team's Discord channel (linked from the README's "Stay In Touch" section) is the fastest way to ask questions about internals. For bigger design discussions, the vuejs/rfcs repository is the right venue.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Debugging – Vue.js wiki | Factory