Skip to content

Latest commit

 

History

History
27 lines (21 loc) · 6.07 KB

File metadata and controls

27 lines (21 loc) · 6.07 KB

Changelog

v1.0.0 - 2026-05-15

First release. Pinned to vue ^3.5.34 + nuxt ^4.4.5 on Node 20+ (22 recommended).

Added

  • 10 rules:
    • vue-nuxt-anti-patterns - 38 LLM regressions with BAD / CORRECT pairs covering Options API in new components, Vue.use / new Vue boot, template filters (removed in Vue 3), $on/$off/$emit event bus, .sync modifier, created() / beforeDestroy(), $set / $delete, ref(null) template refs (Vue 3.5 introduced useTemplateRef), toRefs(props) boilerplate (Vue 3.5 destructure is reactive), withDefaults wrapping (Vue 3.5 made it redundant), Vuex createStore, Pinia options-style stores, module-scope ref() leaks in Nuxt composables (cross-request SSR pollution), manual Vue imports inside Nuxt SFCs, missing imports in plain Vite + Vue, setup() inside <script setup>, defineComponent in SFC, missing onWatcherCleanup(), mutating nested fields on shallowRef useAsyncData payloads (Nuxt 4 default), missing key on shared useFetch / useAsyncData (Nuxt 4 singleton-by-key), awaiting same-key useAsyncData twice, readBody in GET handlers, server route filenames without method suffix, raw Error from server route (use createError), pages/components/composables at root in Nuxt 4 (must be under app/), compatibilityVersion: 3 in Nuxt 4 (flag removed), store/ directory (Nuxt 2 / Vuex naming), queryContent in @nuxt/content v3, @nuxt/ui v3 component anatomy, Vue Router v4 patterns where v5 changed (ESM-only), Pinia v2 patterns where v3 changed, Vitest v3 default pool assumption, Cypress component tests as recommended path, raw addEventListener over useEventListener, hand-rolled click-outside, hand-rolled debounce, static <Teleport> to lazily-mounted target, eager hydration of below-the-fold async components
    • vue-3-5-core - the Vue 3.5 trio LLMs miss: useTemplateRef('name'), useId() for SSR-safe ARIA, reactive props destructure with defaults (no withDefaults, no toRefs), plus onWatcherCleanup(), <Teleport defer>, lazy hydration via defineAsyncComponent({ hydrate: hydrateOnVisible / hydrateOnIdle / hydrateOnInteraction / hydrateOnMediaQuery })
    • vue-script-setup - <script setup lang="ts"> canonical shape: defineProps / defineEmits (tuple form) / defineModel / defineSlots / defineOptions / defineExpose, generic components via <script setup generic="T">, no setup() nesting, no defineComponent in SFC
    • nuxt-4-core - app/ srcDir for client code, server/ shared/ public/ modules/ at root, no compatibilityVersion (removed in Nuxt 4), compatibilityDate instead, split TypeScript projects (.app, .server, .shared), client + server auto-imports, Nitro 2.13 stable + h3 1.15 stable (NOT v3 / v2 betas)
    • nuxt-data-fetching - useFetch / useAsyncData return shallowRef by default in Nuxt 4 (mutate by replacement, not nested write), singleton-by-key (two same-key calls share state), reactive keys via getter functions, transform / pick / default / watch options, error handling via createError, lazy / useLazyFetch for non-blocking loads
    • nuxt-state-management - decision tree (ref for component-local, useState for request-scoped shared, Pinia for cross-route persistent), why module-scope ref() in a Nuxt composable is a SSR cross-request leak, composable vs store choice, hydration safety
    • nuxt-server-routes - server/api/ filename method suffixes (.get, .post, .put, .delete, .patch), defineEventHandler, getValidatedQuery + readValidatedBody with Zod, createError({ statusCode, statusMessage, data }), server middleware patterns, useRuntimeConfig for secrets, file-upload validation
    • pinia - Pinia 3 setup-store canonical shape, storeToRefs for reactive destructure, no mapState / mapGetters (legacy), acceptHMRUpdate block, $patch / $reset / $subscribe / $onAction, @pinia/nuxt integration, isolated unit testing via setActivePinia(createPinia())
    • vueuse - VueUse 14 foundational composables (useEventListener, onClickOutside, useDebounceFn / useThrottleFn, useIntersectionObserver, useDark / useColorMode, useStorage, useMediaQuery, useElementSize, useScroll, useFocus, useClipboard)
    • vue-nuxt-testing - Vitest 4 + Vue Test Utils 2 + @nuxt/test-utils + Playwright. Vitest 4 default pool flipped from 'threads' to 'forks'. happy-dom over jsdom. mountSuspended / renderSuspended for Nuxt-aware mounts. Cypress component tests NOT the recommended path
  • 5 skills: /vue-new-component, /nuxt-new-server-route, /nuxt-new-pinia-store, /vue-nuxt-migrate-to-3-5-and-4, /vue-nuxt-validate
  • 1 reviewer agent (vue-nuxt-reviewer) with severity grouping (CRITICAL / ERROR / WARN / NIT) and per-file checks
  • Fixture projects: correct-sample (gold-standard Vue 3.5.34 + Nuxt 4.4.5 + Pinia 3 + Nuxt UI 4 + Zod) and anti-pattern-sample (16 distinct numbered violations across 6 files, pinned to vue ^3.3.0 + nuxt ^3.0.0 + vuex ^4.1.0 to demonstrate the v3.3 / v3 / Vuex hangover)
  • POSIX-friendly bash validation script with optional hanko validate integration

Notes on the wedge vs the existing community Vue / Nuxt rules

The canonical Vue and Nuxt rules on cursor.directory pre-date Vue 3.5 (released 2024-09) and Nuxt 4 (released 2025-07). Across vue.mdc, vue3-composition-api-cursorrules-prompt-file.mdc, vue-3-nuxt-3-development-cursorrules-prompt-file.mdc, vue-pinia-cursorrules-prompt-file.mdc, vue-claude-stack.mdc, and the largest single file sanjeed5/nuxt.mdc (387 lines), zero mention useTemplateRef, useId, reactive props destructure with defaults, Nuxt 4, the app/ srcDir layout, the shallowRef default on useAsyncData, the singleton-by-key behaviour, or onWatcherCleanup(). The largest file (sanjeed5/nuxt.mdc) still teaches the store/ directory (deprecated for stores/ even in Nuxt 3, and app/stores/ in Nuxt 4). This plugin's vue-3-5-core and nuxt-4-core rules teach the modern shape; vue-nuxt-anti-patterns rule entries #8, #9, #10, #18, #25, #26, #27, #37, #38 reject the pre-3.5 / pre-4 forms by name with BAD / CORRECT pairs.