Skip to main content
skill CX Codex

motion · mindrally — Claude Code skill: what it does, how to install

Guides coding agents to build hardware-accelerated animations using the Motion library in vanilla JavaScript and TypeScript.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add Mindrally/skills --skill motion -a claude-code
Open on GitHub

What motion does

This skill equips coding assistants with implementation standards for the vanilla Motion library (npm install motion). It provides structured patterns for animate, timeline, scroll, inView, and stagger.

The core focus is browser rendering performance. The prompt instructs models to avoid layout-triggering properties like width or top, favoring GPU-accelerated transforms like scale, x, and y. It also covers temporary will-change allocation and accessibility via prefers-reduced-motion.

For React applications, this skill is unsuited: the guidelines explicitly direct you to use motion/react instead.

What it helps with

  • build scroll-linked progress and parallax animations
  • orchestrate staggered timeline sequences across DOM elements
  • optimize frame rates by replacing layout properties with transforms
  • implement accessible animations respecting reduced-motion settings

Example prompts for the agent

  • Create a staggered reveal animation for .card elements using motion
  • Animate the page progress bar on scroll with vanilla Motion
  • Build a sequence timeline for header and footer using GPU transforms

How to install motion

1Skills CLI (Vercel)

npx skills add Mindrally/skills --skill motion -a claude-code

2Manually: put the files in place

~/.claude/skills/motion/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/motion/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about motion

How to install motion in Claude Code?

Run npx skills add Mindrally/skills --skill motion -a claude-code. Alternatively, copy the file to ~/.claude/skills/motion/SKILL.md.

What does the motion skill do?

It provides guidelines for writing smooth web animations with Motion in vanilla JS and TS. It steers the assistant toward GPU transforms, timelines, and scroll observers.

Can I use this skill for React codebases?

No, these guidelines target vanilla JavaScript and TypeScript projects. React applications require the separate motion/react package.

Source text

SKILL.md · Apache-2.0
---
name: motion
description: Expert guidelines for building performant animations with Motion (formerly Motion One) vanilla JavaScript animation library
metadata:
  maintainer: Mindrally
  source: https://github.com/Mindrally/skills
---

# Motion Animation Guidelines

You are an expert in Motion (motion.dev), JavaScript, TypeScript, and web animation performance. Follow these guidelines when creating animations.

## Core Principles

### About Motion
- Motion is the JavaScript animation library from the creator of Framer Motion
- Use `motion` for vanilla JavaScript/TypeScript projects
- Use `motion/react` for React projects (see framer-motion skill)
- Designed for high performance with minimal bundle size

### Installation
```bash
npm install motion
```

### Basic Import
```javascript
import { animate, scroll, inView, timeline } from "motion";
```

## Basic Animations

### Simple Animation
```javascript
import { animate } from "motion";

// Animate a single element
animate(".element", { x: 100, opacity: 1 }, { duration: 0.5 });

// Animate with options
animate(
  ".element",
  { transform: "translateX(100px)" },
  {
    duration: 0.8,
    easing: "ease-out"
  }
);
```

### Keyframes
```javascript
animate(
  ".element",
  {
    x: [0, 100, 50],      // Keyframe values
    opacity: [0, 1, 0.5]
  },
  { duration: 1 }
);
```

## Performance Optimization

### Animate Transform Properties
```javascript
// Best performance - GPU accelerated
animate(".element", {
  x: 100,           // translateX
  y: 50,            // translateY
  scale: 1.2,       // scale
  rotate: 45,       // rotate
  opacity: 0.5      // opacity
});

// Avoid when possible - triggers layout
animate(".element", {
  width: 200,       // Causes layout recalculation
  height: 150,      // Causes layout recalculation
  top: 50,          // Causes layout recalculation
  left: 100         // Causes layout recalculation
});
```

### Use will-change
```javascript
// Add will-change for transform animations
const element = document.querySelector(".element");
element.style.willChange = "transform";

animate(element, { x: 100 }, {
  onComplete: () => {
    element.style.willChange = "auto"; // Remove after animation
  }
});
```

### Hardware Acceleration
Motion automatically uses hardware-accelerated properties when possible. For best performance:

1. Prefer `x`, `y` over `left`, `top`
2. Prefer `scale` over `width`, `height`
3. Use `opacity` for fade effects
4. Use `rotate` over `transform: rotate()`

## Timeline Animations

### Create Timelines
```javascript
import { timeline } from "motion";

const sequence = [
  [".header", { y: ["-100%", 0], opacity: [0, 1] }],
  [".content", { y: [50, 0], opacity: [0, 1] }, { at: "-0.3" }],
  [".footer", { y: [50, 0], opacity: [0, 1] }, { at: "-0.3" }]
];

const controls = timeline(sequence, {
  duration: 0.8,
  defaultOptions: { easing: "ease-out" }
});
```

### Timeline Controls
```javascript
const controls = timeline(sequence);

controls.play();
controls.pause();
controls.reverse();
controls.stop();
controls.finish();

// Seek to specific time
controls.currentTime = 0.5;
```

## Scroll Animations

### Basic Scroll Animation
```javascript
import { scroll, animate } from "motion";

scroll(
  animate(".progress-bar", { scaleX: [0, 1] }),
  { target: document.querySelector("article") }
);
```

### Scroll-Linked Animation
```javascript
scroll(({ y }) => {
  // y.progress is 0 to 1
  animate(".element", {
    opacity: y.progress,
    y: y.progress * 100
  }, { duration: 0 });
});
```

### Scroll with Container
```javascript
scroll(
  animate(".parallax", { y: [0, -100] }),
  {
    target: document.querySelector(".section"),
    offset: ["start end", "end start"]
  }
);
```

## In-View Animations

### Trigger on Visibility
```javascript
import { inView, animate } from "motion";

inView(".card", (info) => {
  animate(info.target, { opacity: 1, y: 0 }, { duration: 0.5 });

  // Return cleanup function
  return () => {
    animate(info.target, { opacity: 0, y: 20 }, { duration: 0.2 });
  };
});
```

### With Options
```javascript
inView(
  ".element",
  (info) => {
    animate(info.target, { scale: [0.8, 1], opacity: [0, 1] });
  },
  {
    margin: "-100px",  // Trigger 100px before entering viewport
    amount: 0.5        // Trigger when 50% visible
  }
);
```

## Stagger Animations

### Stagger Multiple Elements
```javascript
import { stagger, animate } from "motion";

animate(
  ".list-item",
  { opacity: [0, 1], y: [20, 0] },
  { delay: stagger(0.1) }
);
```

### Stagger from Center
```javascript
animate(
  ".grid-item",
  { scale: [0, 1] },
  { delay: stagger(0.05, { from: "center" }) }
);
```

### Stagger with Easing
```javascript
animate(
  ".item",
  { x: ["-100%", 0] },
  {
    delay: stagger(0.1, {
      easing: "ease-out",
      start: 0.2
    })
  }
);
```

## Spring Animations

### Use Springs for Natural Motion
```javascript
animate(
  ".element",
  { scale: 1.2 },
  {
    easing: "spring",
    // or with custom spring settings
    easing: [0.34, 1.56, 0.64, 1] // Custom bezier curve
  }
);
```

### Spring Options
```javascript
animate(".element", { x: 100 }, {
  type: "spring",
  stiffness: 300,
  damping: 30
});
```

## Easing Functions

### Built-in Easings
```javascript
// Common easing values
animate(".element", { x: 100 }, { easing: "ease" });
animate(".element", { x: 100 }, { easing: "ease-in" });
animate(".element", { x: 100 }, { easing: "ease-out" });
animate(".element", { x: 100 }, { easing: "ease-in-out" });
animate(".element", { x: 100 }, { easing: "linear" });

// Cubic bezier
animate(".element", { x: 100 }, {
  easing: [0.25, 0.1, 0.25, 1]
});
```

## Animation Controls

### Control Playback
```javascript
const controls = animate(".element", { x: 100 }, { duration: 1 });

// Control methods
controls.play();
controls.pause();
controls.stop();
controls.finish();
controls.reverse();

// Get/set time
controls.currentTime = 0.5;
console.log(controls.duration);

// Cancel animation
controls.cancel();
```

### Animation Events
```javascript
const controls = animate(
  ".element",
  { x: 100 },
  {
    duration: 1,
    onComplete: () => console.log("Done!")
  }
);

// Promise-based
controls.finished.then(() => {
  console.log("Animation finished");
});
```

## Accessibility

### Respect Reduced Motion
```javascript
const prefersReducedMotion = window.matchMedia(
  "(prefers-reduced-motion: reduce)"
).matches;

animate(
  ".element",
  { x: 100, opacity: 1 },
  {
    duration: prefersReducedMotion ? 0 : 0.5,
    easing: prefersReducedMotion ? "linear" : "ease-out"
  }
);
```

### Create Accessible Wrapper
```javascript
function safeAnimate(element, keyframes, options = {}) {
  const reducedMotion = window.matchMedia(
    "(prefers-reduced-motion: reduce)"
  ).matches;

  return animate(element, keyframes, {
    ...options,
    duration: reducedMotion ? 0 : (options.duration ?? 0.3)
  });
}
```

## Integration with Frameworks

### Vanilla JavaScript
```javascript
document.addEventListener("DOMContentLoaded", () => {
  animate(".hero", { opacity: [0, 1], y: [30, 0] });
});
```

### With Event Listeners
```javascript
const button = document.querySelector(".button");

button.addEventListener("mouseenter", () => {
  animate(button, { scale: 1.05 }, { duration: 0.2 });
});

button.addEventListener("mouseleave", () => {
  animate(button, { scale: 1 }, { duration: 0.2 });
});
```

## Cleanup

### Cancel Animations
```javascript
const controls = animate(".element", { x: 100 });

// Later, cancel it
controls.cancel();
```

### Cleanup Pattern
```javascript
class AnimatedComponent {
  constructor(element) {
    this.element = element;
    this.animations = [];
  }

  animate(keyframes, options) {
    const controls = animate(this.element, keyframes, options);
    this.animations.push(controls);
    return controls;
  }

  destroy() {
    this.animations.forEach(anim => anim.cancel());
    this.animations = [];
  }
}
```

## Best Practices Summary

1. Use transform properties (x, y, scale, rotate) for best performance
2. Add will-change before complex animations, remove after
3. Use timeline for sequenced animations
4. Use scroll() for scroll-linked effects
5. Use inView() for viewport-triggered animations
6. Use stagger() for animating multiple elements
7. Prefer springs for interactive/gesture animations
8. Always respect reduced motion preferences
9. Cancel animations when no longer needed
10. Test performance on actual devices

© Mindrally · Apache-2.0 · Mindrally/skills

Similar skills

Everything for Frontend and UI →

motion by other authors comes first.

motion motiondivision This skill guides Motion and CSS animation work, finds docs and examples, and helps inspect performance issues. Use it when building UI motion or upgrading Motion. CX Codex +1 717installs motion secondsky A skill that feeds your agent the Motion (Framer Motion) docs for React: drag-and-drop, scroll effects, layout transitions. Useful when the agent guesses at props. CX Codex +1 1,100installs frontend-design official anthropics This skill guides intentional visual design for new interfaces and redesigns. Use it when a generic generated UI is not enough. 1,025,790installs design-taste-frontend Leonxlnx This skill directs the design of public pages and work screens, then checks the result in a browser through screenshots. Use it when an interface feels generic or unfinished. CX Codex +1 678,700installs prototype Matt Pocock Creates throwaway prototypes for checking state logic or exploring UI before committing the decision to the main codebase. 986,201installs hyperframes heygen-com Instructs coding agents on creating, validating, and rendering HTML-based videos using the HyperFrames framework and CLI. CX Codex +1 1,200,000installs hyperframes-cli heygen-com Controls HyperFrames video workflows from the CLI: audits layouts and contrast, edits timeline clips, captures snapshots, and renders locally or in cloud runtimes. CX Codex +1 1,300,000installs webapp-testing official anthropics This skill tests local web apps with Playwright, helping agents debug UI behavior, capture screenshots, and inspect browser logs. 186,758installs

From the same set236

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor