# React Spring Mouse Tracking Example: Building Spring-Based Cursor Animations with Emil Kowalski's Skills

> Build physics-based cursor animations in React with @react-spring. Explore a React Spring mouse tracking example using useSpring and animated.div for smooth, engaging UI effects.

- Repository: [Emil Kowalski/skills](https://github.com/emilkowalski/skills)
- Tags: tutorial
- Published: 2026-08-06

---

**Use `@react-spring/web` with `useSpring()` and `animated.div` to create a physics-based cursor follower where tension (170) and friction (26) control the spring stiffness and damping.**

The **skills** repository by Emil Kowalski is a curated collection of AI-assisted UI design workflows. Each skill is a markdown-based instruction set that guides agents through opinionated animation and prototyping tasks. This article walks through applying the **prototype** skill to generate a React Spring mouse tracking component—no hand-tuned keyframes required.

## What Is the Skills Repository?

The repository at `emilkowalski/skills` contains no executable code. Instead, it stores **skill definitions**: plain-text `.md` files with front matter (`name`, `description`) and step-by-step workflows for AI agents.

According to the root [README.md](https://github.com/emilkowalski/skills/blob/main/README.md), the project exists because "Agents don't have great taste" and need structured guidance to produce usable UI artifacts【1†L29-L38】.

Key locations in the repo:

- [`skills/animate/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/animate/SKILL.md) — Full animation construction workflow
- [`skills/prototype/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/prototype/SKILL.md) — Multi-variant prototyping with visual picker
- [`skills/pick-ui-library/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/pick-ui-library/SKILL.md) — Library selection guidelines
- [`skills/animation-vocabulary/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/animation-vocabulary/SKILL.md) — Standardized motion terminology

## The Prototype Skill Workflow for React Spring Mouse Tracking

The **prototype** skill in [`skills/prototype/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/prototype/SKILL.md) prescribes a six-phase process for generating UI variants【3†L25-L48】. Here's how it applies to our React Spring mouse tracking example.

### Phase 1: Scope Definition

Define a single, focused UI element. For mouse tracking, this is a circular cursor follower with spring physics.

### Phase 2: Stack Reconnaissance

Identify the toolchain. The prototype skill directs agents to select proven libraries over hand-rolled solutions. We choose:

- **React** — Component framework
- **@react-spring/web** — Physics-based animation (the `useSpring` hook and `animated` components)

### Phase 3: Variant Generation

Generate 2–3 genuinely different implementations. The baseline below uses default spring physics; variants could adjust `tension`/`friction` or add visual effects like trails.

### Phase 4: Picker Harness

The skill includes a [`PICKER.md`](https://github.com/emilkowalski/skills/blob/main/PICKER.md) file with markup for a live variant switcher. In production, agents copy this verbatim to render all variants behind a toggle.

### Phase 5: Verification

Ensure the snippet runs without console errors in React 17+.

### Phase 6: Promotion

Once selected, move the component into the main codebase and delete prototype files.

## Complete React Spring Mouse Tracking Code

Here's the production-ready implementation following the prototype skill's structure:

```tsx
import { useSpring, animated } from '@react-spring/web';
import { useEffect } from 'react';

export default function SpringMouseTracker() {
  const [{ x, y }, api] = useSpring(() => ({ x: 0, y: 0 }));

  useEffect(() => {
    const handleMouseMove = (e: MouseEvent) => {
      api.start({
        x: e.clientX,
        y: e.clientY,
        config: { tension: 170, friction: 26 },
      });
    };

    window.addEventListener('mousemove', handleMouseMove);
    return () => window.removeEventListener('mousemove', handleMouseMove);
  }, [api]);

  return (
    <animated.div
      style={{
        position: 'fixed',
        left: 0,
        top: 0,
        width: 20,
        height: 20,
        borderRadius: '50%',
        background: 'rgba(0, 150, 255, 0.6)',
        pointerEvents: 'none',
        transform: x
          .to((xVal) => `translate3d(${xVal - 10}px, ${y.get() - 10}px, 0)`),
      }}
    />
  );
}

```

### Key Implementation Details

| Aspect | Implementation |
|--------|---------------|
| **Spring initialization** | `useSpring(() => ({ x: 0, y: 0 }))` returns `[values, api]` |
| **Physics config** | `tension: 170, friction: 26` — balanced snappiness with natural decay |
| **Event handling** | Global `mousemove` listener updates spring target via `api.start()` |
| **Performance** | `translate3d` GPU acceleration; `pointerEvents: 'none'` prevents interaction blocking |
| **Cleanup** | `useEffect` cleanup removes listener to prevent memory leaks |

## Understanding the Spring Physics Parameters

The `config` object in `@react-spring/web` controls motion behavior:

- **Tension (default 170)** — Higher values create stiffer, faster springs. Lower values feel loose and heavy.
- **Friction (default 26)** — Higher values increase damping, reducing oscillation. Lower values cause more bounce.

For React Spring mouse tracking, 170/26 provides responsive cursor following without excessive wobble. For a "heavier" feel, try `tension: 120, friction: 30`. For elastic overshoot, reduce friction to `friction: 10`.

## Alternative Variants for the Picker

The **prototype** skill encourages multiple implementations. Consider these variants:

**Snappy variant** (`tension: 300, friction: 30`) — Near-instant cursor lock with minimal overshoot.

**Liquid variant** (`tension: 50, friction: 20`) — Slow, dreamy follow with visible lag.

**Trail variant** — Multiple `animated.div` elements with staggered spring targets creating a ribbon effect.

## Applying the Animate Skill for Refinement

Once the prototype is selected, the **animate** skill from [`skills/animate/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/animate/SKILL.md) can refine the motion. Its workflow includes:

1. **Gate** — Verify animation is necessary (yes: provides feedback)
2. **Purpose** — Clarify the intent (cursor presence indicator)
3. **Tool selection** — Confirm `@react-spring/web` vs. CSS transitions
4. **Properties** — Position (`x`, `y`) vs. opacity, scale
5. **Easing** — Spring physics vs. cubic-bezier
6. **Duration** — Physics-derived (natural) vs. fixed ms
7. **Exit** — Add cleanup animation on unmount

The skill's decision tree prevents agents from defaulting to arbitrary durations or mismatched easing curves【2†L1-L4】.

## Using the Skills CLI

Install and invoke skills directly:

```bash

# One-time installation

npx skills@latest add emilkowalski/skills

# Generate a React Spring mouse tracking prototype

skills prototype "Build a spring-based mouse follower in React with 3 physics variants"

```

The CLI reads [`skills/prototype/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/prototype/SKILL.md), executes its six-phase workflow, and returns the component code plus picker harness.

## Summary

- The **skills** repository encodes UI design workflows as markdown instruction sets for AI agents.
- The **prototype** skill provides a structured six-phase process for generating and comparing UI variants.
- **React Spring mouse tracking** requires `useSpring()` for physics values, `api.start()` for updates, and `animated.div` for GPU-accelerated rendering.
- Spring `tension` and `friction` parameters directly control response speed and damping—no keyframe math needed.
- The **animate** skill offers a secondary refinement pass with gates for necessity, tool selection, and motion quality.

## Frequently Asked Questions

### What makes @react-spring/web suitable for mouse tracking?

`@react-spring/web` uses a physics simulation rather than duration-based animation. For mouse tracking, this means the follower naturally accelerates and decelerates based on cursor velocity, producing organic motion that CSS transitions cannot replicate. The `useSpring` hook accepts new targets via `api.start()` without interrupting in-flight animation, ensuring smooth handoffs between rapid cursor movements.

### How do I prevent the React Spring mouse tracker from lagging behind?

Lag is intentional physics behavior—it's the spring's natural response time. To reduce perceived lag, increase `tension` (stiffness) or decrease `friction` (damping). For instant following, set `immediate: true` in `api.start()`, though this defeats the spring purpose. Consider whether the lag serves your UX goal: it creates visual weight and can reduce cognitive load by smoothing erratic cursor movements.

### Can I track mouse position without adding a global event listener?

Yes, but with trade-offs. You could attach `onMouseMove` to a parent container, limiting tracking to that element. However, `position: fixed` overlay cursors typically need `window` events. Ensure cleanup in the `useEffect` return function to prevent memory leaks when the component unmounts—this is explicitly checked in the **animate** skill's "Verify" phase.

### Where does the skills repository store its animation guidelines?

All guidelines live in [`skills/animate/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/animate/SKILL.md) (core workflow) and [`skills/animation-vocabulary/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/animation-vocabulary/SKILL.md) (terminology standards). The animate skill references these to enforce consistent decision-making: gates prevent unnecessary motion, the tool selection step mandates spring or CSS appropriately, and the properties section restricts animatable attributes to performant choices (transform, opacity) rather than layout triggers.