A maintenance release. CI had been failing since May 2026, and because Lint ran first, every typecheck, test and build step was being skipped — including the Vue CanvasEffects typecheck added in v3.5.2. All 155 lint errors are now cleared and the pipeline runs end to end, green.
Roughly two thirds turned out to be misconfiguration rather than bad code.
🩹 Configuration
54 false positives from the plain-JS no-unused-vars rule running on TypeScript .vue files. It read the parameter names inside type annotations as unused runtime params:
type: Function as PropType<(id: string) => boolean> // ← "'id' is never used"
isDateUnavailable?: (date: DateValue) => boolean // ← "'date' is never used"Renaming those to _id / _date would have silenced the rule while making the types less readable. The TS-aware rule is used instead.
vue/multi-word-component-names (49) disabled for the component library. Button.vue, Card.vue and Alert.vue are the public API. The rule guards app components against colliding with HTML elements — not applicable to a namespaced kit installed via the shadcn CLI.
no-undef off for .vue files. They're TypeScript, which already reports undefined identifiers and understands bundler-replaced process.env.NODE_ENV — which is why the React ErrorBoundary using the identical expression was never flagged.
Underscore-prefixed bindings honoured as the existing "deliberately unused" marker, and .claude/ excluded from linting (it holds stale git worktrees — whole second copies of the repo — worth 76 duplicate errors locally).
🐛 Real fixes
- Cascading renders removed from six components.
Header,CanvasSettings,settings-pageandToursynced state from props inside an effect; they now adjust during render — React's documented pattern — so nothing paints a stale value for a frame first. useIsMobilerewritten withuseSyncExternalStore. It rendered once withundefined, then set state in an effect: a cascading render, and a frame of desktop layout on a phone.- Dot Matrix Studio's shape preview no longer reads a ref during render. It used a ref plus a tick counter rendered into a hidden
<span>to force updates. The preview is now state and the hack is gone. - Latest-ref writes moved out of render in
AnimationPanelanduseExport. KbdCombo.vueno longer duplicatesKbd'scvablock — twenty lines of class strings kept alive purely to derive a type, never applied, and free to drift from the styles actually in use.
Upgrading
Non-breaking; no API changes. Registry content did change for carousel, dropzone, shapes, tour and Vue kbd, so re-run add for those if you want the fixes.
🔬 Internals
Three genuine false positives in React's new hooks rules (react-hooks/refs on a render-prop call built entirely from useState values, static-components on a lucide icon lookup, set-state-in-effect on Embla's imperative init) carry targeted suppressions with stated reasons rather than contorted code.
Verified beyond the linter, since several of these changed real behaviour: 677 root + 114 Vue tests passing, both typecheck projects clean, registry audit 0/0, production build green, plus browser checks of client-side navigation, the canvas effects, and the studio shape preview (still previews live during a drag and commits on release).
Full diff: v3.5.2...v3.5.3