
awwwards-animations
Professional React animation skill for creating Awwwards/FWA-level animations using GSAP (useGSAP), Motion (Framer Motion), Anime.js, and Lenis. Use when building premium scroll experiences, custom cursors, page transitions, text animations, parallax effects, micro-interactions, or any animation that needs to be 60fps and award-worthy. Triggers on requests for smooth scroll, ScrollTrigger, magnetic effects, reveal animations, horizontal scroll, pin sections, stagger effects, useScroll, useTransform, integration with Three.js/WebGL, algorithmic art, mathematical art, generative art, fractals, L-systems, flow fields, strange attractors, sacred geometry, geometric puzzles, Dudeney dissections, tangram, tessellations, Penrose tiles, kinetic typography, glitch effects, text explosion, morphing text, circular text, brutalist design, minimalist animation, neo-brutalism, or design philosophy mixing. React-first approach with proper cleanup and hooks.
- Installs
- 2.9K
- Last 24h
- +15
- Trending rank
- #7059
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/devmartinese/awwwards-animations-skill --skill awwwards-animations- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads awwwards-animations automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Awwwards Animations
Create premium web animations at Awwwards/FWA quality level. React-first approach. 60fps non-negotiable.
Decision Matrix
| Task | Library | Why |
|---|---|---|
| Scroll-driven animations | GSAP + ScrollTrigger + useGSAP | Industry standard, best control |
| Smooth scroll | Lenis + ReactLenis | Best performance, works with ScrollTrigger |
| React-native animations | Motion (Framer Motion) | Native React, useScroll/useTransform |
| Simple/lightweight effects | Anime.js 4.0 | Small footprint, clean API |
| Complex timelines | GSAP | Unmatched timeline control |
| SVG morphing | GSAP MorphSVG or Anime.js | Both excellent |
| 3D + animation | Three.js + GSAP | GSAP controls Three.js objects |
| Page transitions | AnimatePresence or GSAP | Motion for React, GSAP for complex |
| Geometric shapes (vector) | SVG + GSAP/Motion | Native, animable |
| Geometric shapes (canvas) | Canvas 2D API | Programmatic, performant |
| Pseudo-3D shapes | Zdog | Flat design 3D, ~2kb |
| Creative coding/generative | p5.js | Rich ecosystem |
| Audio reactive | Tone.js | Web Audio, synths, effects |
| Physics 2D | Matter.js | Gravity, collisions, constraints |
| Algorithmic/generative art | Canvas 2D + p5.js | Math-driven visuals |
| Fractals/L-systems | Canvas 2D recursivo | Recursive rendering |
| Tessellations/geometric puzzles | SVG + GSAP | Precise animated transforms |
| Kinetic typography advanced | GSAP SplitText + Canvas | Per-char control |
| Glitch effects | CSS + GSAP | Layered RGB split, clip-path |
| Brutalist animation | CSS raw + Motion | Hard cuts, no easing |
| Minimalist animation | Motion springs | Subtle, purposeful motion |
Installation (Latest Stable - 2025)
# GSAP + React hook (v3.14.1)
npm install gsap @gsap/react
# Lenis (v1.3.17) - includes React components
npm install lenis
# Motion (Framer Motion)
npm install motion
# Anime.js (v4.0.0)
npm install animejs
React Setup
1. GSAP Configuration (app-wide)
// lib/gsap.ts
'use client' // Next.js App Router
import gsap from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'
import { useGSAP } from '@gsap/react'
// Register plugins once
gsap.registerPlugin(ScrollTrigger, useGSAP)
export { gsap, ScrollTrigger, useGSAP }
2. Lenis + GSAP ScrollTrigger Integration (Critical)
// components/SmoothScroll.tsx
'use client'
import { ReactLenis, useLenis } from 'lenis/react'
import { useEffect } from 'react'
import { gsap, ScrollTrigger } from '@/lib/gsap'
export function SmoothScroll({ children }: { children: React.ReactNode }) {
const lenis = useLenis()
useEffect(() => {
if (!lenis) return
lenis.on('scroll', ScrollTrigger.update)
gsap.ticker.add((time) => lenis.raf(time * 1000))
gsap.ticker.lagSmoothing(0)
return () => { gsap.ticker.remove(lenis?.raf) }
}, [lenis])
return (
<ReactLenis root options={{ lerp: 0.1, duration: 1.2, smoothWheel: true }}>
{children}
</ReactLenis>
)
}
// Wrap in layout: <SmoothScroll>{children}</SmoothScroll>
Core Patterns (React)
Detailed implementations in references:
- GSAP + useGSAP: See references/gsap-react.md
- Motion (Framer Motion): See references/motion-patterns.md
- Anime.js 4.0: See references/animejs-react.md
- Lenis React: See references/lenis-react.md
- Geometric Shapes: See references/geometric-shapes.md (SVG, Canvas, Zdog, p5.js, Tetris-style)
- Audio Reactive: See references/audio-reactive.md (Tone.js, Web Audio, scroll audio)
- Physics 2D: See references/physics-2d.md (Matter.js, collisions, constraints)
- Advanced (Three.js, WebGL): See references/advanced-patterns.md
- Algorithmic & Generative Art: See references/algorithmic-art.md (fractals, L-systems, flow fields, attractors, noise, sacred geometry)
- Advanced Text Effects: See references/text-effects.md (glitch, kinetic typography, morphing, explosion, circular text, scramble)
- Geometric Puzzles: See references/geometric-puzzles.md (Dudeney, tangram, tessellations, Penrose, polyominoes)
- Design Philosophy: See references/design-philosophy.md (brutalist, minimalist, abstract, mixing styles, palettes)
- Performance: See references/performance.md
Quick Patterns (React)
1. Magnetic Cursor (GSAP + useGSAP)
'use client'
import { useRef, useEffect } from 'react'
import { gsap, useGSAP } from '@/lib/gsap'
export function MagneticCursor() {
const cursorRef = useRef<HTMLDivElement>(null)
const pos = useRef({ x: 0, y: 0, cx: 0, cy: 0 })
useEffect(() => {
const h = (e: MouseEvent) => { pos.current.x = e.clientX; pos.current.y = e.clientY }
window.addEventListener('mousemove', h)
return () => window.removeEventListener('mousemove', h)
}, [])
useGSAP(() => {
gsap.ticker.add(() => {
const p = pos.current
p.cx += (p.x - p.cx) * 0.15; p.cy += (p.y - p.cy) * 0.15
gsap.set(cursorRef.current, { x: p.cx, y: p.cy })
})
})
return <div ref={cursorRef} className="fixed w-10 h-10 border border-white rounded-full pointer-events-none mix-blend-difference z-[9999] -translate-x-1/2 -translate-y-1/2" />
}
2. Magnetic Button (Motion)
'use client'
import { useRef, useState } from 'react'
import { motion } from 'motion/react'
export function MagneticButton({ children }: { children: React.ReactNode }) {
const ref = useRef<HTMLButtonElement>(null)
const [pos, setPos] = useState({ x: 0, y: 0 })
const onMove = (e: React.MouseEvent) => {
const { left, top, width, height } = ref.current!.getBoundingClientRect()
setPos({ x: (e.clientX - left - width / 2) * 0.3, y: (e.clientY - top - height / 2) * 0.3 })
}
return (
<motion.button ref={ref} onMouseMove={onMove} onMouseLeave={() => setPos({ x: 0, y: 0 })}
animate={pos} transition={{ type: 'spring', stiffness: 150, damping: 15 }}
className="px-8 py-4 bg-white text-black rounded-full">{children}</motion.button>
)
}
3. Parallax Hero (GSAP + useGSAP)
'use client'
import { useRef } from 'react'
import { gsap, ScrollTrigger, useGSAP } from '@/lib/gsap'
export function ParallaxHero() {
const containerRef = useRef<HTMLDivElement>(null)
useGSAP(() => {
gsap.to('.parallax-bg', {
yPercent: 50,
ease: 'none',
scrollTrigger: {
trigger: containerRef.current,
start: 'top top',
end: 'bottom top',
scrub: true,
},
})
gsap.to('.hero-title', {
yPercent: 100,
opacity: 0,
scrollTrigger: {
trigger: containerRef.current,
start: 'top top',
end: '50% top',
scrub: true,
},
})
}, { scope: containerRef })
return (
<div ref={containerRef} className="relative h-screen overflow-hidden">
<div className="parallax-bg absolute inset-0 bg-cover bg-center" />
<h1 className="hero-title absolute inset-0 flex items-center justify-center text-6xl">
Hero Title
</h1>
</div>
)
}
4. Text Character Reveal (Motion)
'use client'
import { motion } from 'motion/react'
const container = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: { staggerChildren: 0.02 },
},
}
const child = {
hidden: { opacity: 0, y: 50, rotateX: -90 },
visible: {
opacity: 1,
y: 0,
rotateX: 0,
transition: { type: 'spring', damping: 12 },
},
}
export function TextReveal({ text }: { text: string }) {
return (
<motion.span
variants={container}
initial="hidden"
whileInView="visible"
viewport={{ once: true }}
className="inline-block"
>
{text.split('').map((char, i) => (
<motion.span key={i} variants={child} className="inline-block">
{char === ' ' ? '\u00A0' : char}
</motion.span>
))}
</motion.span>
)
}
5. Image Reveal (GSAP)
'use client'
import { useRef } from 'react'
import { gsap, useGSAP } from '@/lib/gsap'
export function ImageReveal({ src, alt }: { src: string; alt: string }) {
const containerRef = useRef<HTMLDivElement>(null)
useGSAP(() => {
gsap.from(containerRef.current, {
clipPath: 'inset(100% 0% 0% 0%)',
duration: 1.2,
ease: 'power4.inOut',
scrollTrigger: {
trigger: containerRef.current,
start: 'top 80%',
},
})
gsap.from('.reveal-img', {
scale: 1.3,
duration: 1.5,
ease: 'power2.out',
scrollTrigger: {
trigger: containerRef.current,
start: 'top 80%',
},
})
}, { scope: containerRef })
return (
<div ref={containerRef} className="overflow-hidden">
<img src={src} alt={alt} className="reveal-img w-full h-full object-cover" />
</div>
)
}
6. Glitch Text Effect (CSS + GSAP)
'use client'
import { useRef, useEffect } from 'react'
import { gsap } from '@/lib/gsap'
export function GlitchText({ text }: { text: string }) {
const ref = useRef<HTMLDivElement>(null)
useEffect(() => {
const layers = ref.current!.querySelectorAll('.g-layer')
const tl = gsap.timeline({ repeat: -1, repeatDelay: 3 })
tl.to(layers[0], { x: -5, duration: 0.05, ease: 'none' }, 0)
.to(layers[0], { x: 5, duration: 0.05 }, 0.05)
.to(layers[0], { x: 0, duration: 0.05 }, 0.1)
.to(layers[1], { x: 5, duration: 0.05 }, 0.02)
.to(layers[1], { x: -5, duration: 0.05 }, 0.07)
.to(layers[1], { x: 0, duration: 0.05 }, 0.12)
return () => { tl.kill() }
}, [])
return (
<div ref={ref} className="relative font-mono text-5xl font-black">
<span className="relative z-10">{text}</span>
<span className="g-layer absolute inset-0 text-cyan-400 mix-blend-multiply" aria-hidden>{text}</span>
<span className="g-layer absolute inset-0 text-red-400 mix-blend-multiply" aria-hidden>{text}</span>
</div>
)
}
7. Fractal Tree (Canvas 2D)
'use client'
import { useRef, useEffect } from 'react'
export function FractalTree({ depth = 10, angle = 25 }: { depth?: number; angle?: number }) {
const canvasRef = useRef<HTMLCanvasElement>(null)
useEffect(() => {
const canvas = canvasRef.current!
const ctx = canvas.getContext('2d')!
canvas.width = canvas.offsetWidth * 2; canvas.height = canvas.offsetHeight * 2; ctx.scale(2, 2)
let progress = 0, raf = 0
function branch(x: number, y: number, len: number, a: number, d: number) {
if (d > depth || len < 2) return
const dp = Math.max(0, Math.min(1, progress * depth - d))
if (dp <= 0) return
const ex = x + Math.cos(a * Math.PI / 180) * len * dp
const ey = y - Math.sin(a * Math.PI / 180) * len * dp
ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(ex, ey)
ctx.strokeStyle = `hsl(${120 + d * 15}, 60%, ${30 + d * 5}%)`
ctx.lineWidth = Math.max(1, (depth - d) * 1.5); ctx.stroke()
branch(ex, ey, len * 0.72, a + angle, d + 1)
branch(ex, ey, len * 0.72, a - angle, d + 1)
}
const animate = () => {
progress = Math.min(1, progress + 0.008)
ctx.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight)
branch(canvas.offsetWidth / 2, canvas.offsetHeight, canvas.offsetHeight * 0.28, 90, 0)
if (progress < 1) raf = requestAnimationFrame(animate)
}
animate()
return () => cancelAnimationFrame(raf)
}, [depth, angle])
return <canvas ref={canvasRef} className="w-full h-full bg-gray-950" />
}
See references/algorithmic-art.md for L-systems, flow fields, attractors, noise, sacred geometry.
8. Geometric Dissection (SVG + GSAP)
'use client'
import { useRef, useState } from 'react'
import { gsap } from '@/lib/gsap'
const P = [
{ id: 'A', tri: 'M 0,173 L 50,87 L 100,173 Z', sq: 'M 0,0 L 100,0 L 100,87 L 0,87 Z', c: '#f43f5e' },
{ id: 'B', tri: 'M 50,87 L 100,0 L 150,87 Z', sq: 'M 100,0 L 200,0 L 200,87 L 100,87 Z', c: '#8b5cf6' },
{ id: 'C', tri: 'M 100,173 L 150,87 L 200,173 Z', sq: 'M 0,87 L 100,87 L 100,173 L 0,173 Z', c: '#06b6d4' },
{ id: 'D', tri: 'M 50,87 L 100,173 L 150,87 L 100,0 Z', sq: 'M 100,87 L 200,87 L 200,173 L 100,173 Z', c: '#f59e0b' },
]
export function GeometricDissection() {
const svg = useRef<SVGSVGElement>(null)
const [isSq, setSq] = useState(false)
const morph = () => {
const t = !isSq
P.forEach((p, i) => {
const el = svg.current!.querySelector(`#d-${p.id}`)
if (el) gsap.to(el, { attr: { d: t ? p.sq : p.tri }, duration: 1.5, ease: 'power2.inOut', delay: i * 0.15 })
}); setSq(t)
}
return (
<div className="flex flex-col items-center gap-4">
<svg ref={svg} viewBox="-10 -10 220 200" className="w-64 h-64">
{P.map(p => <path key={p.id} id={`d-${p.id}`} d={p.tri} fill={p.c} stroke="#000" strokeWidth="1.5" />)}
</svg>
<button onClick={morph} className="px-6 py-2 bg-white text-black font-mono text-sm">{isSq ? '△' : '□'}</button>
</div>
)
}
See references/geometric-puzzles.md for tangram, tessellations, Penrose tiles, polyominoes.
9. Brutalist Grid (Motion)
'use client'
import { motion } from 'motion/react'
export function BrutalistGrid({ items }: { items: string[] }) {
return (
<div className="grid grid-cols-3 border-2 border-black">
{items.map((item, i) => (
<motion.div key={i}
className="border-2 border-black p-6 font-mono font-black uppercase text-2xl"
style={{ mixBlendMode: i % 2 === 0 ? 'normal' : 'difference' }}
initial={{ opacity: 0 }} whileInView={{ opacity: 1 }} viewport={{ once: true }}
transition={{ duration: 0, delay: i * 0.1 }}
whileHover={{ backgroundColor: '#000', color: '#BAFF39', transition: { duration: 0 } }}
>{item}</motion.div>
))}
</div>
)
}
Design Philosophy (Quick Reference)
| Style | Motion Feel | Easing | Typography | Key Trait |
|---|---|---|---|---|
| Brutalist | Hard, instant, jarring | none / steps() | Mono, 15-30vw | Raw honesty |
| Minimalist | Smooth, subtle, slow | power2.out | Sans-serif light | Purposeful restraint |
| Abstract | Noise-driven, parametric | Organic/sine | Varies | Mathematical beauty |
| Neo-Brutalist | Bold but controlled | power1.out | Mono + color | Brutalism + restraint |
See references/design-philosophy.md for full guide with color palettes and mixing strategies.
Easing Reference
| Feel | GSAP | Motion |
|---|---|---|
| Smooth | power2.out | [0.16, 1, 0.3, 1] |
| Snappy | power4.out | [0.87, 0, 0.13, 1] |
| Bouncy | back.out(1.7) | { type: 'spring', stiffness: 300, damping: 20 } |
| Dramatic | power4.inOut | [0.76, 0, 0.24, 1] |
Timing
- Micro-interactions: 150-300ms
- UI transitions: 300-500ms
- Page transitions: 500-800ms
- Stagger: 0.02-0.1s per item
Accessibility
// Motion: useReducedMotion() → conditionally disable/reduce animations
import { useReducedMotion } from 'motion/react'
const reduced = useReducedMotion() // true if prefers-reduced-motion: reduce
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
Performance Rules
- Only animate
transformandopacity - Use
will-changesparingly - Always cleanup:
useGSAPhandles it automatically - Scope GSAP selectors to container refs
- Use
contextSafe()for event handlers with GSAP - Memoize Motion variants objects
Common Pitfalls
- Not integrating Lenis with ScrollTrigger
- Missing
scopein useGSAP - Not using
contextSafe()for click handlers - React 18 Strict Mode calling effects twice
- Forgetting
'use client'in Next.js App Router - Not calling
ScrollTrigger.refresh()after dynamic content
Testing Checklist
- 60fps on scroll (Chrome DevTools Performance)
- Keyboard navigation works
- Respects prefers-reduced-motion
- No layout shifts (CLS)
- Mobile touch works
- ScrollTrigger markers removed in prod
- No memory leaks on unmount
Inspiration
Active Theory, Studio Freight, Locomotive, Resn, Aristide Benoist, Immersive Garden
FAQ
What does the awwwards-animations skill do?
Professional React animation skill for creating Awwwards/FWA-level animations using GSAP (useGSAP), Motion (Framer Motion), Anime.js, and Lenis. Use when building premium scroll experiences, custom cursors, page transitions, text animations, parallax effects, micro-interactions, or any animation that needs to be 60fps and award-worthy. Triggers on requests for smooth scroll, ScrollTrigger, magnetic effects, reveal animations, horizontal scroll, pin sections, stagger effects, useScroll, useTransform, integration with Three.js/WebGL, algorithmic art, mathematical art, generative art, fractals, L-systems, flow fields, strange attractors, sacred geometry, geometric puzzles, Dudeney dissections, tangram, tessellations, Penrose tiles, kinetic typography, glitch effects, text explosion, morphing text, circular text, brutalist design, minimalist animation, neo-brutalism, or design philosophy mixing. React-first approach with proper cleanup and hooks.
How do I install awwwards-animations?
Run npx skills add https://github.com/devmartinese/awwwards-animations-skill --skill awwwards-animations in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/awwwards-animations/ (personal) or .claude/skills/awwwards-animations/ (project).
Which AI agents can use awwwards-animations?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is awwwards-animations safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains awwwards-animations?
It is published by devmartinese in devmartinese/awwwards-animations-skill. It has 2,894 recorded installs.
Popular frontend & design skills
setup-matt-pocock-skills
mattpocock/skills
Configure this repo for the engineering skills: set up its issue tracker, triage label vocabulary, and domain doc layout. Run once before first use of the other engineering skills.
frontend-design
anthropics/skills
Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.
hyperframes-animation
heygen-com/hyperframes
All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus Lottie, Three.js, Anime.js, CSS keyframes, Web Animations API, TypeGPU). Use for any motion or animation task: pick 2-4 rules and compose, or load a blueprint, or look up runtime-specific API (e.g. GSAP eases / Lottie player / Three.js mixer). Also covers auditing an existing composition's choreography (animation map) and 24 named text-animation effects. HyperFrames-native: single paused timeline, seek-safe, deterministic.
prototype
mattpocock/skills
Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.
hyperframes-core
heygen-com/hyperframes
The HyperFrames composition contract — build one renderable project. Use for composition structure, the data- timing attributes, class="clip", tracks, sub-compositions, variables, framework-owned media playback, deterministic-render rules, and validation. Read before writing composition HTML.
vercel-react-best-practices
vercel-labs/agent-skills
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.