All notable changes to Vuer are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Rule-id stability promise: a vue/... rule id is never reused or silently
re-severed. Removing a rule is a major-version event announced here.
-
Phase 3: the
performance,accessibility, andarchitecturecategories are now populated (11 new rules, 26 total):performance:
no-v-if-with-v-for—v-ifandv-foron the same element are discouraged in Vue 3; filter with a computed instead (Medium).no-deep-watch-without-handler—watch(src, cb, { deep: true })traverses the whole object graph on every change (Low).no-reactive-in-v-for—ref/reactive/computedwrappers created inside loop bodies allocate an effect per iteration that is never released (Low).no-large-list-without-virtualization— heuristic:v-forover a curated set of large-looking collection names without a virtual-scroll wrapper (Low, documented heuristic).
accessibility:
no-img-without-alt— screen readers announce an<img>by itsalttext;alt=""and bound forms are accepted (Medium).no-click-without-role-keyboard—@clickon a non-interactive element with neitherrolenor a keyboard handler is unreachable for keyboard-only users (Medium).no-form-without-label— fields must be labelled via<label for>, a wrapping<label>, oraria-label/aria-labelledby(Medium).no-button-without-type— a<button>defaults tosubmit, which submits the form on any click (Low).
architecture:
no-side-effect-in-computed— assignments, mutating calls,fetch/watch/emit, andasyncgetters insidecomputed(...)are re-run unpredictably by Vue (Medium).no-mutation-of-props— writes toprops.xor a destructureddefinePropsvalue break one-way data flow (Medium).no-async-setup-without-error-boundary— heuristic:async setup()without a<Suspense>boundary renders nothing until the promise settles (Low).
- SFC extraction no longer truncates a
<script>/<style>block when its body contains a bare<that is not a tag opener (e.g.i < items.length): the boundary scanner previously skipped to the next>— the closing tag's — and silently dropped the whole block, silencing every script rule for that file. - Integration snapshot path filters now accept Windows separators and
JSON-escaped
\\separators, so the suite runs on Windows. .gitattributespins every tracked file to LF:core.autocrlf=truerewrote conformance fixtures and insta snapshots to CRLF at checkout, failing the snapshot suite on Windows while CI stayed green.
no-window-open-blank-noopeneris now taint-gated: a provably clean URL (a hardcoded literal, or a value derived only from trusted data) is no longer reported — the reverse-tabnabbing surface requires an attacker-influenced URL. A URL carrying untrusted data is still reported at High, with the source→sink flow path in the diagnostic. This closes the remainingwindow.opensink from the Phase 2 list.no-watch-with-callbackis now scope-aware: watchers created inside a component (<script setup>or Options API) are disposed automatically by Vue, so they are no longer reported. Onlywatchcalls at module scope in a plain<script>block — the one place the watcher has no lifecycle to be torn down with — are flagged, with a corrected message and help text.oxcbumped 0.136/0.143 → 0.144 — the whole cohort moves together (parser, allocator, ast, ast_visit, span, syntax, diagnostics), removing the mixed-generation lockfile. Breaking changes absorbed:Expression::MetaPropertysplit intoImportMeta/NewTarget, andArrowFunctionExpression.bodybecame theArrowFunctionBodyenum (FunctionBody| inherited expression) withas_expression()accessors. The conformance, edge-case, offset-integrity, and snapshot suites pass with zero diffs.- MSRV lowered 1.97 → 1.95 —
oxc0.144 requires rustc 1.95.0, which is now the highest minimum in the dependency tree; CI pinsdtolnay/rust-toolchain1.95.0 to match. oxcre-bumped 0.144/0.147 → 0.149 — renovate had moved the direct dependencies one at a time, leaving threeoxc_allocatorgenerations in the lockfile and mismatchedAllocatortypes at theoxc_parsercall sites; the cohort is single-versioned again. No source changes were needed for this step; the conformance, edge-case, offset-integrity, and snapshot suites pass with zero diffs.- MSRV raised 1.95 → 1.96 —
oxc0.149 requires rustc 1.96.0, which is again the highest minimum in the dependency tree; CI pinsdtolnay/rust-toolchain1.98.0, which stays above the floor.
- Taint analysis engine (
src/taint/) — a single-pass, deterministic, intra-file analysis that annotates every script and template expression with its taint state:- sources:
localStorage/sessionStorage.getItem,fetch/axios/useFetch,useRoute()/$route,definePropsprops, Options APIprops/data/computed,event/$event,window.location,location.search/hash,document.cookie/referrer,document.*DOM reads,FormData/URLSearchParams; - propagators: assignment, concatenation, template literals, ternaries,
member writes/reads, destructuring,
.map/.filter/.thencallbacks,ref/computed/reactive, and bounded inter-procedural flow through local function calls; - sanitizers:
DOMPurify.sanitize,sanitize,escapeHtml,htmlEscape,escape,xssdowngrade taint; - results exposed per expression span via
TaintResult::status_at/flow_at.
- sources:
- Taint-gated rules —
no-v-html,no-inner-html,no-dynamic-bind-src, andno-open-redirectnow report only when the matched pattern carries untrusted data, cutting false positives while keeping the unsafe path fully reported. - Flow paths in diagnostics — pretty output shows
= note: taint from <source> reaches <sink> via <ids>; JSON output gains a structuredflowfield;--listshows the rule kind (taint/syntactic). RuleKindon theRuletrait (defaults toSyntactic) andRule::checkreturningVec<Finding>(diagnostic + optional flows).- Determinism property suite (
tests/determinism.rs) — repeated scans produce byte-identical JSON/SARIF.
no-dangerous-urlstays syntactic by design: the dangerous pattern is the literaljavascript:/data:/vbscript:scheme itself (seedocs/audits.md).- Shared fixtures now seed realistic tainted sources; integration snapshots updated accordingly.
- Initial release: SFC extraction, template parser,
oxc-based script analysis, 15 rules acrosssecurityandbest-practice, pretty/JSON/ minimal/SARIF output, inline suppression, config discovery, parallel scanning, Phase 1 parser-hardening suites (conformance corpus, edge cases, offset integrity).