arkenv
Answer questions about ArkEnv and help implement environment variable validation. Use when developers: (1) Ask about environment…
Build animations in a Nuxt app with nanime, the Nuxt module wrapping Anime.js v4. Use when animating elements, text, SVG or scroll in Nuxt: useAnimate, useWaapiAnimate, useAnimatable, useAnimeTimeline, useDraggable, useSplitText, useScrambleText, useAnimeScroll, useAnimeLayout,
Claude Code
$ npx -y skills add onmax/nuxt-skills --skill nanime --agent claude-code
Codex
$ npx skills add onmax/nuxt-skills --skill nanime -a codex -y
Cursor
$ npx skills add onmax/nuxt-skills --skill nanime -a cursor -y
Gemini CLI
$ npx skills add onmax/nuxt-skills --skill nanime -a gemini-cli -y
GitHub Copilot
$ npx skills add onmax/nuxt-skills --skill nanime -a github-copilot -y
OpenCode
$ npx skills add onmax/nuxt-skills --skill nanime -a opencode -y
Windsurf
$ npx skills add onmax/nuxt-skills --skill nanime -a windsurf -y
name: nanime description: | Build animations in a Nuxt app with nanime, the Nuxt module wrapping Anime.js v4. Use when animating elements, text, SVG or scroll in Nuxt: useAnimate, useWaapiAnimate, useAnimatable, useAnimeTimeline, useDraggable, useSplitText, useScrambleText, useAnimeScroll, useAnimeLayout, <AnimeTransition>, <AnimeTransitionGroup>, <AnimeLayoutGroup>, transition styles, component defaults, provideAnimeDefaults and the #nanime/* aliases. Also use when an effect seems to need raw animejs, GSAP or CSS transition classes. Most mistakes here do not throw; they animate the wrong thing.
The composables own an Anime.js instance, rebuild it when reactive inputs change, and revert it on unmount. They wait for mount, so they are SSR-safe. Composables and components are auto-imported and auto-registered.
Don't drop to `onMounted` with raw `animejs` imports, and don't reach for GSAP or transition CSS. The effect almost always has a nanime path.
| Building | Use | Details | |---|---|---| | Animating elements, refs, arrays, plain objects | `useAnimate` (`useWaapiAnimate` for the Web Animations API) | | | Values set imperatively at speed (cursor follow, live counter) | `useAnimatable` | | | Sequencing | `useAnimeTimeline` | [timelines.md](references/timelines.md) | | Scroll-driven animation | `useAnimeScroll` | [timelines.md](references/timelines.md) | | Text split into lines, words, chars | `useSplitText` | [timelines.md](references/timelines.md) | | Scrambling or revealing text | `useScrambleText` | | | SVG draw, morph, motion path | `#nanime/proxies/svg` inside a composable | [timelines.md](references/timelines.md) | | Dragging with snap, bounds, axis locks | `useDraggable` | [lists.md](references/lists.md) for draggable list items | | `v-if` / `v-show` / keyed enter and leave, crossfades | `<AnimeTransition>` | [transitions.md](references/transitions.md) | | `v-for` add, remove, reorder, stagger | `<AnimeTransitionGroup>` | [transitions.md](references/transitions.md), [lists.md](references/lists.md) | | Mounted elements changing position or size (FLIP) | `<AnimeLayoutGroup>`, or `useAnimeLayout` to `await` it | [layout.md](references/layout.md) | | Testing an animation without a browser | | [verifying.md](references/verifying.md) |
For an Anime.js parameter, return shape or util, read https://animejs.com/documentation. nanime passes those through unchanged. For nanime's own API, read https://nanimejs.netlify.app/llms-full.txt or query the docs MCP server at https://nanimejs.netlify.app/mcp.
Not auto-imported. Import helpers from these, never from `animejs` directly.
| Alias | Holds | |---|---| | `#nanime/types` | Anime.js types (`AnimationParams`, `JSAnimation`, …) and `AnimeTransitionStyle` | | `#nanime/utils` | Anime.js utils (`stagger`, `random`, `set`, …), plus `animate` and `createTimer` for handler code | | `#nanime/easings` | `spring`, `cubicBezier`, `steps`, … | | `#nanime/proxies/svg` | `createMotionPath`, `createDrawable`, `morphTo` | | `#nanime/proxies/text` | `scrambleText`, for use inside animation parameters | | `#nanime/proxies` | Both of the above |
Each of these fails without an error.
useAnimeScroll(() => ({ target: section.value ?? undefined })) // correct
useAnimeScroll({ target: section.value }) // silently wrongA template ref is `null` during setup. A plain object is read once, then, so Anime.js falls back to a default, such as watching `document.body` instead of your element. A getter is read again once the element exists.
Read `.value` yourself: Anime.js does not unwrap Vue refs inside parameters. Template refs are `T | null` while most params take `T | undefined`, so use `?? undefined`, not a cast.
function onClick() {
useAnimate(box, { x: 100 }) // leaks: no effect scope, never reverted
}From a handler or per-frame callback, use `animate` from `#nanime/utils` and own the handle:
import { animate } from '#nanime/utils'
import type { JSAnimation } from '#nanime/types'
const pulse = shallowRef<JSAnimation | null>(null)
onScopeDispose(() => pulse.value?.revert())
function highlight(el: HTMLElement) {
pulse.value?.revert()
pulse.value = animate(el, { scale: [1, 1.1, 1], duration: 400 })
}Code of your own that reads an element must also wait for mount.
nanime unwraps a composable's return value to its Anime.js instance, in parameters and in a timeline's `sync()`:
const scroll = useAnimeScroll(() => ({ target: section.value ?? undefined, sync: true }))
useAnimate(box, { x: 400, autoplay: scroll })One scroll observer drives one animation. Handing it to a second animation steals it from the first, which freezes. Call `useAnimeScroll` once per animation; observers with the same params stay in step.
`{{ animation.progress }}` never updates; the return value tracks the instance, not the numbers inside it. Copy the value out from a callback:
const progress = ref(0)
useAnimate(box, { x: 400, onUpdate: self => progress.value = self.progress })`useScrambleText` and `useSplitText` write into the element. If Vue also renders the changing value there, they overwrite each other. Render the first value once and hand changes to the composable:
<script setup lang="ts">
useScrambleText(title, {}, () => ({ text: track.value.title }))
</script>
<template>
<h2 ref="title" v-once>{{ track.title }}</h2>
</template>For `useSplitText`, keep `v-once` and pass the new text through its `html` option.
AnimeJS `scrambleText()` sets its own `duration`, `delay` and `ease`, so the same keys in `useScrambleText`'s second argume
Answer questions about ArkEnv and help implement environment variable validation. Use when developers: (1) Ask about environment…
Comark (Components in Markdown) parser: syntax, AST, Vue/React/Svelte/Angular renderers, plugins, and LLM streaming with…
Build durable backend AI agents with the eve framework. Use when creating, editing, or debugging an eve project — agent…
Nitro is the framework-agnostic server toolkit (powering Nuxt) for building and deploying web servers anywhere. Use when working…
Guides authentication in Nuxt apps using @nuxtjs/better-auth. Use when installing or configuring the module, using its client or…
Build typed, content-driven Nuxt applications with @nuxt/content. Use when working with content.config.ts, collections,…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.