More powerful alternative to Animated library for React Native with UI thread animations and advanced gesture handling.
—
Pre-built animations for component lifecycle events and layout changes that automatically trigger when components mount, unmount, or change layout properties.
Animations that play when components first mount or appear.
/** Fade in from transparent to opaque */
const FadeIn: IEntryExitAnimationBuilder;
/** Fade in while sliding from left */
const FadeInLeft: IEntryExitAnimationBuilder;
/** Fade in while sliding from right */
const FadeInRight: IEntryExitAnimationBuilder;
/** Fade in while sliding from top */
const FadeInUp: IEntryExitAnimationBuilder;
/** Fade in while sliding from bottom */
const FadeInDown: IEntryExitAnimationBuilder;/** Slide in from left edge */
const SlideInLeft: IEntryExitAnimationBuilder;
/** Slide in from right edge */
const SlideInRight: IEntryExitAnimationBuilder;
/** Slide in from top edge */
const SlideInUp: IEntryExitAnimationBuilder;
/** Slide in from bottom edge */
const SlideInDown: IEntryExitAnimationBuilder;/** Bounce in with scale effect */
const BounceIn: IEntryExitAnimationBuilder;
/** Bounce in from left */
const BounceInLeft: IEntryExitAnimationBuilder;
/** Bounce in from right */
const BounceInRight: IEntryExitAnimationBuilder;
/** Bounce in from top */
const BounceInUp: IEntryExitAnimationBuilder;
/** Bounce in from bottom */
const BounceInDown: IEntryExitAnimationBuilder;/** Zoom in from small to normal size */
const ZoomIn: IEntryExitAnimationBuilder;
/** Zoom in from left corner */
const ZoomInLeft: IEntryExitAnimationBuilder;
/** Zoom in from right corner */
const ZoomInRight: IEntryExitAnimationBuilder;
/** Zoom in from top */
const ZoomInUp: IEntryExitAnimationBuilder;
/** Zoom in from bottom */
const ZoomInDown: IEntryExitAnimationBuilder;
/** Easy zoom in from top */
const ZoomInEasyUp: IEntryExitAnimationBuilder;
/** Easy zoom in from bottom */
const ZoomInEasyDown: IEntryExitAnimationBuilder;
/** Zoom in with rotation effect */
const ZoomInRotate: IEntryExitAnimationBuilder;/** Flip in along X axis from top */
const FlipInXUp: IEntryExitAnimationBuilder;
/** Flip in along X axis from bottom */
const FlipInXDown: IEntryExitAnimationBuilder;
/** Flip in along Y axis from left */
const FlipInYLeft: IEntryExitAnimationBuilder;
/** Flip in along Y axis from right */
const FlipInYRight: IEntryExitAnimationBuilder;
/** Easy flip in along X axis */
const FlipInEasyX: IEntryExitAnimationBuilder;
/** Easy flip in along Y axis */
const FlipInEasyY: IEntryExitAnimationBuilder;/** Rotate in from down-left */
const RotateInDownLeft: IEntryExitAnimationBuilder;
/** Rotate in from down-right */
const RotateInDownRight: IEntryExitAnimationBuilder;
/** Rotate in from up-left */
const RotateInUpLeft: IEntryExitAnimationBuilder;
/** Rotate in from up-right */
const RotateInUpRight: IEntryExitAnimationBuilder;
/** Stretch in horizontally */
const StretchInX: IEntryExitAnimationBuilder;
/** Stretch in vertically */
const StretchInY: IEntryExitAnimationBuilder;
/** Roll in from left */
const RollInLeft: IEntryExitAnimationBuilder;
/** Roll in from right */
const RollInRight: IEntryExitAnimationBuilder;
/** Light speed in from left */
const LightSpeedInLeft: IEntryExitAnimationBuilder;
/** Light speed in from right */
const LightSpeedInRight: IEntryExitAnimationBuilder;
/** Pinwheel in effect */
const PinwheelIn: IEntryExitAnimationBuilder;Usage Examples:
import React, { useState } from "react";
import Animated, {
FadeIn,
SlideInLeft,
BounceIn,
ZoomInRotate
} from "react-native-reanimated";
import { Button } from "react-native";
const EntryAnimationExample = () => {
const [showItems, setShowItems] = useState(false);
return (
<>
<Button
title="Show Items"
onPress={() => setShowItems(!showItems)}
/>
{showItems && (
<>
{/* Basic fade in */}
<Animated.View
entering={FadeIn}
style={{ height: 50, backgroundColor: "red", margin: 5 }}
>
<Animated.Text>Fade In</Animated.Text>
</Animated.View>
{/* Slide in with custom duration */}
<Animated.View
entering={SlideInLeft.duration(800)}
style={{ height: 50, backgroundColor: "blue", margin: 5 }}
>
<Animated.Text>Slide In Left</Animated.Text>
</Animated.View>
{/* Bounce in with delay */}
<Animated.View
entering={BounceIn.delay(500)}
style={{ height: 50, backgroundColor: "green", margin: 5 }}
>
<Animated.Text>Bounce In</Animated.Text>
</Animated.View>
{/* Complex zoom with spring */}
<Animated.View
entering={ZoomInRotate.springify().damping(8)}
style={{ height: 50, backgroundColor: "purple", margin: 5 }}
>
<Animated.Text>Zoom In Rotate</Animated.Text>
</Animated.View>
</>
)}
</>
);
};Animations that play when components unmount or disappear.
// All entry animations have corresponding exit versions
const FadeOut: IEntryExitAnimationBuilder;
const FadeOutLeft: IEntryExitAnimationBuilder;
const FadeOutRight: IEntryExitAnimationBuilder;
const FadeOutUp: IEntryExitAnimationBuilder;
const FadeOutDown: IEntryExitAnimationBuilder;
const SlideOutLeft: IEntryExitAnimationBuilder;
const SlideOutRight: IEntryExitAnimationBuilder;
const SlideOutUp: IEntryExitAnimationBuilder;
const SlideOutDown: IEntryExitAnimationBuilder;
const BounceOut: IEntryExitAnimationBuilder;
const BounceOutLeft: IEntryExitAnimationBuilder;
const BounceOutRight: IEntryExitAnimationBuilder;
const BounceOutUp: IEntryExitAnimationBuilder;
const BounceOutDown: IEntryExitAnimationBuilder;
const ZoomOut: IEntryExitAnimationBuilder;
const ZoomOutLeft: IEntryExitAnimationBuilder;
const ZoomOutRight: IEntryExitAnimationBuilder;
const ZoomOutUp: IEntryExitAnimationBuilder;
const ZoomOutDown: IEntryExitAnimationBuilder;
const ZoomOutEasyUp: IEntryExitAnimationBuilder;
const ZoomOutEasyDown: IEntryExitAnimationBuilder;
const ZoomOutRotate: IEntryExitAnimationBuilder;
// Additional exit animations...Usage Example:
import React, { useState } from "react";
import Animated, {
FadeIn,
FadeOut,
SlideOutRight,
ZoomOutRotate
} from "react-native-reanimated";
import { Button } from "react-native";
const ExitAnimationExample = () => {
const [items, setItems] = useState([1, 2, 3, 4]);
const removeItem = (id: number) => {
setItems(prev => prev.filter(item => item !== id));
};
return (
<>
{items.map((item) => (
<Animated.View
key={item}
entering={FadeIn}
exiting={item % 2 === 0 ? SlideOutRight : ZoomOutRotate}
style={{
height: 60,
backgroundColor: "lightblue",
margin: 5,
borderRadius: 10,
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingHorizontal: 15,
}}
>
<Animated.Text>Item {item}</Animated.Text>
<Button title="Remove" onPress={() => removeItem(item)} />
</Animated.View>
))}
</>
);
};Animations that play when component layout properties change.
/** Default layout transition for position and size changes */
const Layout: ILayoutAnimationBuilder;
/** Linear transition for layout changes */
const LinearTransition: ILayoutAnimationBuilder;
/** Fading transition during layout changes */
const FadingTransition: ILayoutAnimationBuilder;
/** Sequenced transition with staggered timing */
const SequencedTransition: ILayoutAnimationBuilder;
/** Jumping transition with bounce effect */
const JumpingTransition: ILayoutAnimationBuilder;
/** Curved transition with custom path */
const CurvedTransition: ILayoutAnimationBuilder;Usage Example:
import React, { useState } from "react";
import Animated, {
Layout,
LinearTransition,
FadingTransition,
FadeIn,
FadeOut
} from "react-native-reanimated";
import { Button } from "react-native";
const LayoutTransitionExample = () => {
const [items, setItems] = useState([1, 2, 3, 4, 5]);
const [isGrid, setIsGrid] = useState(false);
const addItem = () => {
setItems(prev => [...prev, Math.max(...prev) + 1]);
};
const removeItem = () => {
setItems(prev => prev.slice(0, -1));
};
const shuffle = () => {
setItems(prev => [...prev].sort(() => Math.random() - 0.5));
};
return (
<>
<Button title="Add Item" onPress={addItem} />
<Button title="Remove Item" onPress={removeItem} />
<Button title="Shuffle" onPress={shuffle} />
<Button
title={isGrid ? "List View" : "Grid View"}
onPress={() => setIsGrid(!isGrid)}
/>
<Animated.View
layout={Layout.springify()}
style={{
flexDirection: isGrid ? "row" : "column",
flexWrap: isGrid ? "wrap" : "nowrap",
padding: 10,
}}
>
{items.map((item) => (
<Animated.View
key={item}
entering={FadeIn}
exiting={FadeOut}
layout={LinearTransition.springify()}
style={{
width: isGrid ? "45%" : "100%",
height: 60,
backgroundColor: `hsl(${item * 60}, 70%, 80%)`,
margin: 5,
borderRadius: 10,
justifyContent: "center",
alignItems: "center",
}}
>
<Animated.Text>Item {item}</Animated.Text>
</Animated.View>
))}
</Animated.View>
</>
);
};Custom animations defined using keyframe sequences.
/**
* Creates custom keyframe-based animations
*/
const Keyframe: {
/**
* Define keyframe animation with percentage-based timing
* @param keyframes - Object with percentage keys and style values
* @returns Keyframe animation builder
*/
define(keyframes: Record<string | number, any>): IEntryExitAnimationBuilder;
};
interface ReanimatedKeyframe {
0?: KeyframeProps;
from?: KeyframeProps;
to?: KeyframeProps;
100?: KeyframeProps;
[percent: number]: KeyframeProps;
}
interface KeyframeProps {
transform?: any[];
opacity?: number;
backgroundColor?: string;
// Any animatable style property
[key: string]: any;
}Usage Example:
import React, { useState } from "react";
import Animated, { Keyframe } from "react-native-reanimated";
import { Button } from "react-native";
const KeyframeExample = () => {
const [show, setShow] = useState(false);
// Define custom keyframe animation
const customKeyframe = Keyframe.define({
0: {
opacity: 0,
transform: [{ scale: 0.3 }, { rotate: "0deg" }],
},
25: {
opacity: 0.5,
transform: [{ scale: 0.7 }, { rotate: "90deg" }],
},
50: {
opacity: 0.8,
transform: [{ scale: 1.2 }, { rotate: "180deg" }],
backgroundColor: "red",
},
75: {
opacity: 0.9,
transform: [{ scale: 0.9 }, { rotate: "270deg" }],
backgroundColor: "blue",
},
100: {
opacity: 1,
transform: [{ scale: 1 }, { rotate: "360deg" }],
backgroundColor: "green",
},
}).duration(2000);
// Bouncing keyframe
const bounceKeyframe = Keyframe.define({
from: {
transform: [{ translateY: 0 }],
},
20: {
transform: [{ translateY: -30 }],
},
40: {
transform: [{ translateY: 0 }],
},
60: {
transform: [{ translateY: -15 }],
},
80: {
transform: [{ translateY: 0 }],
},
to: {
transform: [{ translateY: 0 }],
},
}).duration(1000);
return (
<>
<Button title="Toggle" onPress={() => setShow(!show)} />
{show && (
<>
<Animated.View
entering={customKeyframe}
style={{
width: 100,
height: 100,
backgroundColor: "lightblue",
margin: 20,
borderRadius: 10,
}}
>
<Animated.Text>Custom</Animated.Text>
</Animated.View>
<Animated.View
entering={bounceKeyframe.delay(500)}
style={{
width: 100,
height: 100,
backgroundColor: "lightcoral",
margin: 20,
borderRadius: 10,
}}
>
<Animated.Text>Bounce</Animated.Text>
</Animated.View>
</>
)}
</>
);
};All layout animations can be customized using the builder pattern.
interface IEntryExitAnimationBuilder {
/** Set animation duration in milliseconds */
duration(durationMs: number): IEntryExitAnimationBuilder;
/** Add delay before animation starts */
delay(delayMs: number): IEntryExitAnimationBuilder;
/** Convert to spring-based animation */
springify(): IEntryExitAnimationBuilder;
/** Set spring damping factor */
damping(dampingFactor: number): IEntryExitAnimationBuilder;
/** Set spring mass */
mass(mass: number): IEntryExitAnimationBuilder;
/** Set spring stiffness */
stiffness(stiffnessFactor: number): IEntryExitAnimationBuilder;
/** Set spring overshoot clamping */
overshootClamping(overshootClamping: number): IEntryExitAnimationBuilder;
/** Set rest displacement threshold */
restDisplacementThreshold(threshold: number): IEntryExitAnimationBuilder;
/** Set rest speed threshold */
restSpeedThreshold(threshold: number): IEntryExitAnimationBuilder;
/** Add completion callback */
withCallback(callback: (finished: boolean) => void): IEntryExitAnimationBuilder;
/** Set initial values for the animation */
withInitialValues(values: StyleProps): IEntryExitAnimationBuilder;
/** Add random delay for staggered effects */
randomDelay(): IEntryExitAnimationBuilder;
/** Build the final animation function */
build(): LayoutAnimationFunction;
}
interface ILayoutAnimationBuilder {
/** Set animation duration in milliseconds */
duration(durationMs: number): ILayoutAnimationBuilder;
/** Add delay before animation starts */
delay(delayMs: number): ILayoutAnimationBuilder;
/** Convert to spring-based animation */
springify(): ILayoutAnimationBuilder;
/** Set spring damping factor */
damping(dampingFactor: number): ILayoutAnimationBuilder;
/** Set spring mass */
mass(mass: number): ILayoutAnimationBuilder;
/** Set spring stiffness */
stiffness(stiffnessFactor: number): ILayoutAnimationBuilder;
/** Set spring overshoot clamping */
overshootClamping(overshootClamping: number): ILayoutAnimationBuilder;
/** Set rest displacement threshold */
restDisplacementThreshold(threshold: number): ILayoutAnimationBuilder;
/** Set rest speed threshold */
restSpeedThreshold(threshold: number): ILayoutAnimationBuilder;
/** Add completion callback */
withCallback(callback: (finished: boolean) => void): ILayoutAnimationBuilder;
/** Add random delay for staggered effects */
randomDelay(): ILayoutAnimationBuilder;
/** Build the final animation function */
build(): LayoutAnimationFunction;
}Configuration Examples:
import Animated, {
FadeIn,
SlideInLeft,
Layout,
BounceIn
} from "react-native-reanimated";
// Custom duration and delay
const customFadeIn = FadeIn.duration(800).delay(200);
// Spring-based animation with custom physics
const springSlide = SlideInLeft
.springify()
.damping(15)
.stiffness(200)
.mass(1.2);
// Animation with callback
const bounceWithCallback = BounceIn
.duration(1000)
.withCallback((finished) => {
if (finished) {
console.log("Bounce animation completed!");
}
});
// Layout transition with custom spring
const customLayout = Layout
.springify()
.damping(20)
.stiffness(100)
.randomDelay(); // Adds random delay for staggered effect
// Usage in components
const ConfiguredAnimations = () => (
<>
<Animated.View entering={customFadeIn}>
<Animated.Text>Custom Fade</Animated.Text>
</Animated.View>
<Animated.View entering={springSlide} layout={customLayout}>
<Animated.Text>Spring Slide</Animated.Text>
</Animated.View>
</>
);type LayoutAnimationFunction = (values: LayoutAnimationValues) => LayoutAnimation;
type EntryExitAnimationFunction =
| ((targetValues: EntryAnimationsValues) => LayoutAnimation)
| ((targetValues: ExitAnimationsValues) => LayoutAnimation);
interface LayoutAnimation {
initialValues: StyleProps;
animations: StyleProps;
callback?: (finished: boolean) => void;
}
interface EntryAnimationsValues {
targetOriginX: number;
targetOriginY: number;
targetWidth: number;
targetHeight: number;
targetBorderRadius: number;
targetGlobalOriginX: number;
targetGlobalOriginY: number;
windowWidth: number;
windowHeight: number;
}
interface ExitAnimationsValues {
currentOriginX: number;
currentOriginY: number;
currentWidth: number;
currentHeight: number;
currentBorderRadius: number;
currentGlobalOriginX: number;
currentGlobalOriginY: number;
windowWidth: number;
windowHeight: number;
}
interface LayoutAnimationValues extends EntryAnimationsValues, ExitAnimationsValues {}
enum LayoutAnimationType {
ENTERING = 1,
EXITING = 2,
LAYOUT = 3,
}
interface BaseLayoutAnimationConfig {
duration?: number;
easing?: EasingFunction;
type?: LayoutAnimationType;
dampingRatio?: number;
mass?: number;
stiffness?: number;
overshootClamping?: number;
restDisplacementThreshold?: number;
restSpeedThreshold?: number;
}Install with Tessl CLI
npx tessl i tessl/npm-react-native-reanimated