Framer Motion is a production-ready motion library for React that provides a comprehensive animation and gesture API. It enables developers to create fluid, performant animations through declarative components and hooks, supporting everything from simple transitions to complex gesture-based interactions like drag, pan, and hover.
npm install framer-motionimport { motion, AnimatePresence, useAnimation, Reorder } from "framer-motion";For specific entry points:
// Full feature set (default)
import { motion, m, AnimatePresence, useAnimation } from "framer-motion";
// DOM-only utilities without React components
import { animate, scroll, inView } from "framer-motion/dom";
// Minimal motion components for code splitting
import { m } from "framer-motion/m";
// Ultra-minimal animation hook
import { useAnimate } from "framer-motion/mini";
// Client-side motion namespace (all HTML/SVG elements)
import { motion } from "framer-motion/client";
// Debug utilities and performance stats
import { recordStats } from "framer-motion/debug";
// Minimal DOM animations (ultra-lightweight)
import { animate, animateSequence } from "framer-motion/dom/mini";import { motion, AnimatePresence, useAnimation, Reorder } from "framer-motion";
import { useState } from "react";
function App() {
const [isVisible, setIsVisible] = useState(true);
const [items, setItems] = useState([1, 2, 3, 4]);
const controls = useAnimation();
return (
<div>
{/* Basic motion component with animations */}
<motion.div
initial={{ opacity: 0, y: 50 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.95 }}
drag
dragConstraints={{ left: 0, right: 300, top: 0, bottom: 300 }}
>
Animated content
</motion.div>
{/* Animate presence for enter/exit animations */}
<AnimatePresence>
{isVisible && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
Content that can be toggled
</motion.div>
)}
</AnimatePresence>
{/* Reorderable list */}
<Reorder.Group axis="y" values={items} onReorder={setItems}>
{items.map((item) => (
<Reorder.Item key={item} value={item}>
<div style={{ padding: 20, background: "#f0f0f0", margin: 5 }}>
Item {item}
</div>
</Reorder.Item>
))}
</Reorder.Group>
{/* Imperative animations */}
<motion.div
animate={controls}
onClick={() => controls.start({ rotate: 180 })}
>
Click to rotate
</motion.div>
</div>
);
}Framer Motion is built around several key systems:
motion.div, m.span) that wrap DOM elements with animation capabilitiesAnimatePresence for animating components entering/leaving the DOMCore React components for declarative animations. Supports all HTML and SVG elements with animation props like initial, animate, exit, and gesture handlers.
const motion: {
[K in keyof HTMLElementTagNameMap]: React.ForwardRefExoticComponent<
HTMLMotionProps<K>
>;
} & {
[K in keyof SVGElementTagNameMap]: React.ForwardRefExoticComponent<
SVGMotionProps<SVGElement>
>;
} & {
create<Props>(
Component: string | React.ComponentType<Props>
): React.ForwardRefExoticComponent<MotionProps & Props>;
};
const m: typeof motion; // Minimal version for code splittingImperative animation hooks for programmatic control over animations, including scoped animations and animation controls.
function useAnimate<T extends Element = any>(): [
scope: React.RefObject<T>,
animate: (
target: string | Element,
keyframes: Record<string, any>,
options?: AnimationOptions
) => Promise<void>
];
function useAnimationControls(): LegacyAnimationControls;
interface LegacyAnimationControls {
start(definition?: AnimationDefinition): Promise<any>;
stop(): void;
mount(): () => void;
}Reactive values system for driving animations and sharing state between components, with transformation utilities.
function useMotionValue<T>(initialValue: T): MotionValue<T>;
function useTransform<I, O>(
parent: MotionValue<I> | MotionValue<I>[],
from: I[] | number[],
to: O[] | number[],
options?: TransformOptions<O>
): MotionValue<O>;
function useSpring(
source: MotionValue<number>,
config?: SpringOptions
): MotionValue<number>;Scroll tracking hooks and utilities for scroll-driven animations and viewport intersection detection.
function useScroll(options?: UseScrollOptions): ScrollMotionValues;
function useInView(
ref: React.RefObject<Element>,
options?: UseInViewOptions
): boolean;
function scroll(
onScroll: (info: ScrollInfo) => void,
options?: ScrollOptions
): () => void;
interface ScrollMotionValues {
scrollX: MotionValue<number>;
scrollY: MotionValue<number>;
scrollXProgress: MotionValue<number>;
scrollYProgress: MotionValue<number>;
}Drag controls and gesture event handlers for interactive animations.
function useDragControls(): DragControls;
interface DragControls {
start(event: React.PointerEvent | PointerEvent, options?: StartOptions): void;
cancel(): void;
stop(): void;
}Components for layout animations and enter/exit animations with shared layout transitions.
interface AnimatePresenceProps {
children?: React.ReactNode;
initial?: boolean;
custom?: any;
onExitComplete?: () => void;
mode?: "sync" | "popLayout" | "wait";
root?: HTMLElement | ShadowRoot;
presenceAffectsLayout?: boolean;
propagate?: boolean;
anchorX?: "left" | "right";
}
function AnimatePresence(props: AnimatePresenceProps): JSX.Element;
function LayoutGroup(props: { children: React.ReactNode; id?: string }): JSX.Element;Namespace providing components for creating draggable lists and reorderable collections with smooth animations.
namespace Reorder {
function Group<V>(props: ReorderGroupProps<V>): JSX.Element;
function Item<V>(props: ReorderItemProps<V>): JSX.Element;
}
interface ReorderGroupProps<V> extends Omit<HTMLMotionProps<any>, "values"> {
as?: keyof HTMLElements;
axis?: "x" | "y";
onReorder: (newOrder: V[]) => void;
values: V[];
children: React.ReactNode;
}
interface ReorderItemProps<V> extends Omit<HTMLMotionProps<any>, "value" | "layout"> {
as?: keyof HTMLElements;
value: V;
layout?: true | "position";
children: React.ReactNode;
}Global configuration and feature bundle system for code splitting and performance optimization.
interface MotionConfigProps {
children?: React.ReactNode;
transition?: Transition;
transformPagePoint?: (point: Point) => Point;
reducedMotion?: "always" | "never" | "user";
}
function MotionConfig(props: MotionConfigProps): JSX.Element;
function LazyMotion(props: {
features: FeatureBundle | (() => Promise<FeatureBundle>);
strict?: boolean;
children: React.ReactNode;
}): JSX.Element;Direct DOM animation functions that work without React, for imperative animations and scroll tracking.
function animate(
element: string | Element,
keyframes: Record<string, any> | Record<string, any>[],
options?: AnimationOptions
): AnimationPlaybackControls;
function inView(
element: string | Element,
onStart: (entry: IntersectionObserverEntry) => void | (() => void),
options?: InViewOptions
): () => void;Additional utility hooks for advanced React integration and animation frame management.
function useCycle<T>(...items: T[]): [T, (next?: number) => void];
function useAnimationFrame(callback: (timestamp: number, delta: number) => void): void;
function useForceUpdate(): [() => void, number];Debugging utilities and performance monitoring tools.
function recordStats(): void;Lightweight DOM animation functions for minimal bundle size.
function animateSequence<V extends Record<string, any>>(
sequence: Array<[Element | string, V, AnimationOptions?]>
): Promise<void>;
// Note: animate is re-exported from framer-motion/dom/mini as animateMiniinterface MotionProps {
initial?: boolean | Variant;
animate?: AnimationControls | Variant;
exit?: Variant;
transition?: Transition;
variants?: Variants;
whileHover?: Variant;
whileTap?: Variant;
whileFocus?: Variant;
whileDrag?: Variant;
whileInView?: Variant;
drag?: boolean | "x" | "y";
dragConstraints?: Partial<BoundingBox2D> | React.RefObject<Element>;
onDragStart?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
onDrag?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
onDragEnd?: (event: MouseEvent | TouchEvent | PointerEvent, info: PanInfo) => void;
layout?: boolean | "position" | "size";
layoutId?: string;
onAnimationStart?: (definition: AnimationDefinition) => void;
onAnimationComplete?: (definition: AnimationDefinition) => void;
}
type Variant = string | {
[key: string]: any;
};
interface Variants {
[key: string]: Variant;
}
interface Transition {
duration?: number;
delay?: number;
ease?: Easing | Easing[];
type?: "tween" | "spring" | "keyframes" | "inertia";
bounce?: number;
damping?: number;
mass?: number;
stiffness?: number;
velocity?: number;
restSpeed?: number;
restDelta?: number;
}interface MotionValue<T = any> {
get(): T;
set(v: T, render?: boolean): void;
getPrevious(): T;
getVelocity(): number;
isAnimating(): boolean;
on(eventName: string, callback: (latest: T) => void): () => void;
onChange(callback: (latest: T) => void): () => void;
onRenderRequest(callback: () => void): () => void;
destroy(): void;
}
interface SpringOptions {
stiffness?: number;
damping?: number;
mass?: number;
velocity?: number;
restSpeed?: number;
restDelta?: number;
}interface HTMLElements {
// Extends HTMLElementTagNameMap with all standard HTML elements
[K in keyof HTMLElementTagNameMap]: HTMLElementTagNameMap[K];
}type HTMLMotionProps<T extends keyof HTMLElementTagNameMap> = Omit<
React.HTMLProps<HTMLElementTagNameMap[T]>,
"ref" | "style"
> &
MotionProps & {
style?: MotionStyle;
};
type SVGMotionProps<T> = Omit<React.SVGProps<T>, "ref" | "style"> &
MotionProps & {
style?: MotionStyle;
};
interface MotionStyle extends Omit<React.CSSProperties, "rotate" | "scale" | "perspective"> {
x?: string | number | MotionValue<number | string>;
y?: string | number | MotionValue<number | string>;
z?: string | number | MotionValue<number | string>;
rotate?: string | number | MotionValue<number | string>;
rotateX?: string | number | MotionValue<number | string>;
rotateY?: string | number | MotionValue<number | string>;
rotateZ?: string | number | MotionValue<number | string>;
scale?: string | number | MotionValue<number | string>;
scaleX?: string | number | MotionValue<number | string>;
scaleY?: string | number | MotionValue<number | string>;
scaleZ?: string | number | MotionValue<number | string>;
skew?: string | number | MotionValue<number | string>;
skewX?: string | number | MotionValue<number | string>;
skewY?: string | number | MotionValue<number | string>;
originX?: string | number | MotionValue<number | string>;
originY?: string | number | MotionValue<number | string>;
originZ?: string | number | MotionValue<number | string>;
perspective?: string | number | MotionValue<number | string>;
transformPerspective?: string | number | MotionValue<number | string>;
}