How to Use the Motion Library with motion/react Import Path in taste-skill

The taste-skill repository standardizes on the motion/react import path for all Motion (formerly Framer Motion) animations to ensure lightweight bundles, server-side rendering compatibility, and consistent accessibility patterns.

The taste-skill skill set treats Motion as its canonical animation layer, requiring all UI components to import from motion/react rather than the legacy framer-motion package. This architectural decision, documented in skills/taste-skill/SKILL.md, provides access to React-specific optimizations including the useReducedMotion and useMotionValue hooks while maintaining strict separation between server and client rendering contexts.

Import Standards and Entry Points

The motion/react Entry Point

According to skills/taste-skill/SKILL.md (line 481), the canonical import statement for all animation work is:

import { motion, useReducedMotion } from "motion/react";

This entry point provides the motion component factory alongside essential hooks like useReducedMotion, useMotionValue, and useTransform. Importing from motion/react pulls only the React-specific bundle, keeping application sizes predictable compared to the full Framer Motion package.

Legacy Compatibility

While the older framer-motion package still functions as a legacy alias, line 132 of skills/taste-skill/SKILL.md explicitly states that new code must adopt the motion/react path. The repository's CHANGELOG (line 69) records this migration as part of the architectural standardization to Motion's modern branding and API structure.

Client Component Isolation

Any component utilizing Motion must declare itself as a client component to prevent hydration mismatches. As specified in skills/taste-skill/SKILL.md (line 29), files using Motion must begin with:

"use client";

This directive isolates animation work from server-side rendering, ensuring that motion-specific DOM manipulations and event listeners only execute in the browser environment.

Accessibility and Reduced Motion

The taste-skill architecture prioritizes accessibility through Motion's useReducedMotion hook. For all components where MOTION_INTENSITY exceeds 3, developers must implement reduced-motion handling as shown in line 372 of skills/taste-skill/SKILL.md:

const reduce = useReducedMotion();

return (
  <motion.div
    initial={reduce ? false : { opacity: 0, y: 24 }}
    animate={{ opacity: 1, y: 0 }}
  >
    {children}
  </motion.div>
);

When the user's system preferences indicate prefers-reduced-motion, this pattern renders static fallbacks instead of animations, ensuring compliance with accessibility standards.

Performance Patterns with Motion Values

For high-frequency interactions where MOTION_INTENSITY exceeds 5, taste-skill recommends useMotionValue and useTransform over React state management. Line 57 of skills/taste-skill/SKILL.md documents this "magnetic micro-physics" pattern:

useMotionValue creates mutable motion values that update outside React's render cycle, while useTransform derives new values from these streams without triggering component re-renders. This approach is essential for scroll-driven animations, magnetic cursor effects, and continuous physics simulations that must maintain 60fps.

Code Implementation Examples

Basic Entry Animation

This fade-in component demonstrates the standard pattern with reduced-motion detection:

"use client";

import { motion, useReducedMotion } from "motion/react";

export function FadeIn({ children }: { children: React.ReactNode }) {
  const reduce = useReducedMotion();

  return (
    <motion.div
      initial={reduce ? false : { opacity: 0, y: 24 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.5, ease: "easeOut" }}
    >
      {children}
    </motion.div>
  );
}

Scroll-Reveal Stagger Effects

For feature lists and content reveals, use the stagger pattern documented in skills/taste-skill/SKILL.md (line 775):

"use client";

import { motion, useReducedMotion } from "motion/react";

export function RevealStagger({ items }: { items: string[] }) {
  const reduce = useReducedMotion();

  return (
    <ul className="grid gap-6">
      {items.map((item, i) => (
        <motion.li
          key={item}
          initial={reduce ? false : { opacity: 0, y: 24 }}
          whileInView={{ opacity: 1, y: 0 }}
          viewport={{ once: true, amount: 0.3 }}
          transition={{
            duration: 0.6,
            delay: i * 0.06,
            ease: [0.16, 1, 0.3, 1],
          }}
        >
          {item}
        </motion.li>
      ))}
    </ul>
  );
}

This lightweight alternative to GSAP handles viewport detection and sequential delays without external dependencies.

Magnetic Micro-Physics

For advanced interactions requiring MOTION_INTENSITY greater than 5, implement magnetic button effects using motion values:

"use client";

import { motion, useMotionValue, useTransform, useReducedMotion } from "motion/react";

export function MagneticButton({ children }: { children: React.ReactNode }) {
  const reduce = useReducedMotion();
  if (reduce) return <button>{children}</button>;

  const mouseX = useMotionValue(0);
  const mouseY = useMotionValue(0);
  const rotateX = useTransform(mouseY, [-100, 100], [10, -10]);
  const rotateY = useTransform(mouseX, [-100, 100], [-10, 10]);

  return (
    <motion.button
      className="px-6 py-2 bg-accent text-white rounded"
      style={{ rotateX, rotateY }}
      onMouseMove={e => {
        const rect = e.currentTarget.getBoundingClientRect();
        mouseX.set(e.clientX - rect.left - rect.width / 2);
        mouseY.set(e.clientY - rect.top - rect.height / 2);
      }}
      onMouseLeave={() => {
        mouseX.set(0);
        mouseY.set(0);
      }}
    >
      {children}
    </motion.button>
  );
}

This pattern updates transform values directly on the DOM node, bypassing React's render phase entirely for maximum performance.

Scroll-Driven Opacity

Leverage useScroll and useTransform for scroll-linked effects without manual event listeners:

"use client";

import { motion, useScroll, useTransform, useReducedMotion } from "motion/react";

export function FadeOnScroll({ children }: { children: React.ReactNode }) {
  const reduce = useReducedMotion();
  if (reduce) return <>{children}</>;

  const { scrollYProgress } = useScroll();
  const opacity = useTransform(scrollYProgress, [0, 0.3], [0, 1]);

  return (
    <motion.div style={{ opacity }}>
      {children}
    </motion.div>
  );
}

Summary

  • Import exclusively from motion/react in the taste-skill repository to ensure bundle optimization and access to React-specific APIs.
  • Always declare "use client" at the top of files containing Motion components to prevent server-side hydration errors.
  • Implement useReducedMotion for all animations with intensity greater than 3, returning false for initial states when user preferences require static content.
  • Prefer useMotionValue over state for continuous animations (intensity greater than 5) to avoid expensive re-renders on every frame.
  • Reference skills/taste-skill/SKILL.md lines 132, 29, 57, and 481 for architectural constraints and line 775 for scroll-reveal implementation patterns.

Frequently Asked Questions

Why must I import from "motion/react" instead of "framer-motion"?

The taste-skill repository migrated to Motion's modern branding and bundling architecture, as recorded in the CHANGELOG (line 69). The motion/react entry point provides a lightweight, React-specific bundle that excludes unnecessary platform code, whereas framer-motion imports the legacy full package. This ensures consistent bundle sizes across the skill set and aligns with the architectural standards defined in skills/taste-skill/SKILL.md (line 132).

What happens if I forget to add the "use client" directive to my Motion component?

Omitting the "use client" directive causes server-side rendering attempts to execute Motion's browser-specific APIs (such as window or document references), resulting in hydration mismatches or runtime errors. Line 29 of skills/taste-skill/SKILL.md explicitly requires client-only isolation for all interaction components using Motion to ensure DOM-dependent logic only executes in browser environments.

How does taste-skill handle accessibility for users with motion sensitivities?

The architecture mandates the useReducedMotion hook for any component where MOTION_INTENSITY exceeds 3, as documented in skills/taste-skill/SKILL.md (line 372). When the hook detects prefers-reduced-motion system settings, components render static fallbacks by returning false for initial animation states, ensuring users with vestibular disorders or motion sensitivities receive non-animated content.

When should I use useMotionValue instead of React state for animations?

Use useMotionValue paired with useTransform for continuous, high-frequency updates where MOTION_INTENSITY exceeds 5, such as scroll-linked effects or magnetic cursor interactions described in skills/taste-skill/SKILL.md (line 57). Unlike useState, which triggers React re-renders on every value change, motion values update DOM properties directly through optimized render loops, maintaining 60fps performance without component overhead.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →