How to Implement Lottie Animations in React Native / React
You have a beautiful Lottie animation. It is optimized, under 45KB, and ready to go. Now you need to get it into your React or React Native app. This is where many developers get stuck. The implementation seems straightforward, but there are nuances that can trip you up.
I have implemented Lottie animations in dozens of React and React Native projects. I have made the mistakes. I have debugged the issues. I have learned the best practices. This guide is the result of that experience.
We will cover both React (web) and React Native (mobile). The approaches are similar but have important differences. By the end, you will know exactly how to add Lottie animations to your projects.
Why Lottie in React / React Native?
Before we dive into the code, let us briefly recap why Lottie is such a great fit for React and React Native projects.
React and React Native are component-based. Lottie animations are component-friendly. You can wrap them in a component and reuse them anywhere. They are declarative, just like React itself.
Lottie also solves the performance problems that plague GIFs and videos in React Native. GIFs are heavy and cause jank. Videos are complex to manage. Lottie is lightweight and smooth.
Implementing in React Native
React Native has excellent Lottie support through the lottie-react-native library. Let us walk through the setup and usage.
Installation
The installation process differs between iOS and Android. Here is the full setup.
Step 1: Install the library
npm install lottie-react-native
# or
yarn add lottie-react-native
Step 2: iOS Setup
For iOS, you need to install the native Lottie iOS framework. If you are using CocoaPods, add this to your ios/Podfile:
pod 'lottie-ios'
Then run:
cd ios && pod install
If you are using the new architecture (Fabric), the setup is different. The library version 6.x supports the new architecture.
Step 3: Android Setup
For Android, you need to add the Lottie Android library to your android/app/build.gradle:
dependencies {
implementation 'com.airbnb.android:lottie:6.0.0'
}
You also need to enable the new architecture if you are using it. The library version 6.x supports both old and new architectures.
Step 4: Metro Configuration
Add the following to your metro.config.js to handle Lottie assets:
module.exports = {
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
resolver: {
assetExts: ['lottie'],
},
};
Basic Usage
Once installed, using Lottie in React Native is straightforward.
import React from 'react';
import { View, StyleSheet } from 'react-native';
import LottieView from 'lottie-react-native';
const MyAnimation = () => {
return (
<View style={styles.container}>
<LottieView
source={require('./assets/animations/animation.json')}
autoPlay
loop
style={styles.animation}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
animation: {
width: 200,
height: 200,
},
});
export default MyAnimation;
That is it. A few lines of code and your animation is running.
Controlling the Animation
The real power of Lottie comes from programmatic control. You can play, pause, reset, and control the speed.
import React, { useRef } from 'react';
import { View, Button, StyleSheet } from 'react-native';
import LottieView from 'lottie-react-native';
const ControlledAnimation = () => {
const animationRef = useRef(null);
const handlePlay = () => {
animationRef.current?.play();
};
const handlePause = () => {
animationRef.current?.pause();
};
const handleReset = () => {
animationRef.current?.reset();
};
return (
<View style={styles.container}>
<LottieView
ref={animationRef}
source={require('./assets/animations/animation.json')}
style={styles.animation}
/>
<View style={styles.buttonContainer}>
<Button title="Play" onPress={handlePlay} />
<Button title="Pause" onPress={handlePause} />
<Button title="Reset" onPress={handleReset} />
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
animation: {
width: 200,
height: 200,
},
buttonContainer: {
flexDirection: 'row',
marginTop: 20,
gap: 10,
},
});
export default ControlledAnimation;
Controlling Speed
You can also control the playback speed.
const handleSlowMotion = () => {
animationRef.current?.setProgress(0.5); // 0.5x speed
};
const handleNormalSpeed = () => {
animationRef.current?.setProgress(1);
};
const handleFastSpeed = () => {
animationRef.current?.setProgress(2);
};
Playing Specific Segments
You can play a specific segment of the animation using play with start and end frame parameters.
const handlePlaySegment = () => {
animationRef.current?.play(0, 30); // Play frames 0-30
};
Handling Animation Events
Lottie also provides events you can listen to.
const MyAnimation = () => {
const handleAnimationFinish = () => {
console.log('Animation finished!');
};
const handleAnimationLoop = () => {
console.log('Animation looped!');
};
return (
<LottieView
source={require('./assets/animations/animation.json')}
autoPlay
loop
onAnimationFinish={handleAnimationFinish}
onLoop={handleAnimationLoop}
style={styles.animation}
/>
);
};
Implementing in React (Web)
For web applications, the implementation is similar but uses the lottie-web library.
Installation
npm install lottie-web
# or
yarn add lottie-web
Alternatively, you can use the react-lottie wrapper library for a more React-friendly API:
npm install react-lottie
# or
yarn add react-lottie
Basic Usage with react-lottie
import React from 'react';
import Lottie from 'react-lottie';
import animationData from './assets/animations/animation.json';
const MyAnimation = () => {
const defaultOptions = {
loop: true,
autoplay: true,
animationData: animationData,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice',
},
};
return <Lottie options={defaultOptions} height={200} width={200} />;
};
export default MyAnimation;
Controlling the Animation
With react-lottie, you can control the animation using the isStopped, isPaused, and speed props.
import React, { useState } from 'react';
import Lottie from 'react-lottie';
import animationData from './assets/animations/animation.json';
const ControlledAnimation = () => {
const [isStopped, setIsStopped] = useState(false);
const [isPaused, setIsPaused] = useState(false);
const [speed, setSpeed] = useState(1);
const defaultOptions = {
loop: true,
autoplay: true,
animationData: animationData,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice',
},
};
return (
<div>
<Lottie
options={defaultOptions}
height={200}
width={200}
isStopped={isStopped}
isPaused={isPaused}
speed={speed}
/>
<button onClick={() => setIsStopped(!isStopped)}>Toggle Stop</button>
<button onClick={() => setIsPaused(!isPaused)}>Toggle Pause</button>
<button onClick={() => setSpeed(0.5)}>Slow</button>
<button onClick={() => setSpeed(1)}>Normal</button>
<button onClick={() => setSpeed(2)}>Fast</button>
</div>
);
};
export default ControlledAnimation;
Using lottie-web Directly
If you prefer more control, you can use lottie-web directly with React hooks.
import React, { useEffect, useRef } from 'react';
import lottie from 'lottie-web';
import animationData from './assets/animations/animation.json';
const MyAnimation = () => {
const containerRef = useRef(null);
useEffect(() => {
const instance = lottie.loadAnimation({
container: containerRef.current,
renderer: 'svg',
loop: true,
autoplay: true,
animationData: animationData,
});
return () => {
instance.destroy();
};
}, []);
return <div ref={containerRef} style={{ width: 200, height: 200 }} />;
};
export default MyAnimation;
Optimizing Lottie in React Native
Performance is critical in mobile apps. Here are my tips for optimizing Lottie in React Native.
1. Use dotLottie Format
The dotLottie (.lottie) format is compressed and loads faster. Use it instead of raw JSON when possible.
import { DotLottiePlayer } from '@dotlottie/react-player';
// Instead of LottieView, use DotLottiePlayer for better performance
2. Enable Hardware Acceleration
Set the renderer to 'software' on Android for better performance on older devices. For newer devices, the default is fine.
<LottieView
source={require('./animation.lottie')}
renderer="software" // For Android
autoPlay
loop
/>
3. Freeze Offscreen Animations
Stop rendering animations when they are not visible. Use the freezeOnOffscreen prop.
<LottieView
source={require('./animation.lottie')}
freezeOnOffscreen
autoPlay
loop
/>
4. Use WebGL Renderer for Complex Animations
For complex animations, the WebGL renderer performs better than the default SVG renderer.
<LottieView
source={require('./animation.lottie')}
renderer="webgl"
autoPlay
loop
/>
5. Preload Animations
Preload animations to avoid jank when they first appear.
import { LottieView } from 'lottie-react-native';
// Preload the animation before using it
const animation = require('./assets/animations/animation.lottie');
// Then use it later
<LottieView source={animation} autoPlay />
Common Issues and Solutions
Here are the issues I have encountered most frequently and how to fix them.
Issue 1: Animation Not Rendering on iOS
This is usually a pod installation issue. Ensure you have run pod install after installing the library. Also, make sure your animation file is in the correct location and properly required.
Solution: Clean and rebuild.
cd ios && pod install
cd .. && npx react-native run-ios
Issue 2: Large File Size on Android
Use the dotLottie format instead of JSON. dotLottie files are compressed.
Solution: Convert your JSON to dotLottie using the LottieFiles converter.
Issue 3: Animation Causing Jank
Reduce the complexity of the animation. Use fewer layers and shapes. Or enable WebGL rendering.
Solution: Use renderer="webgl" for complex animations.
Issue 4: Animation Not Looping Properly
Check your animation settings. Use the loop prop and set it to true. Or use setLoop with a reference.
const animationRef = useRef(null);
// Later
animationRef.current?.setLoop(true);
Best Practices
After implementing Lottie in many projects, here are my best practices.
1. Centralize Your Animations
Create a centralized animation registry. This makes it easy to manage and update animations across your app.
// animations/index.js
import animation1 from './animations/animation1.lottie';
import animation2 from './animations/animation2.lottie';
import animation3 from './animations/animation3.lottie';
export const ANIMATIONS = {
loading: animation1,
success: animation2,
error: animation3,
};
// Use it anywhere
import { ANIMATIONS } from './animations';
<LottieView source={ANIMATIONS.loading} autoPlay />
2. Use Theme-Aware Animations
Store theme colors as motion tokens in the dotLottie file. This allows the animation to adapt to light and dark modes automatically.
4. Handle Different Screen Sizes
Use responsive dimensions for your animations. Do not hardcode pixel values.
import { Dimensions } from 'react-native';
const { width, height } = Dimensions.get('window');
<LottieView
source={require('./animation.lottie')}
style={{
width: width * 0.5,
height: height * 0.3,
}}
autoPlay
/>
5. Use Reanimated for Performance
For complex animations that need to respond to gestures or scroll events, use React Native Reanimated with Lottie.
import Animated from 'react-native-reanimated';
import LottieView from 'lottie-react-native';
const AnimatedLottie = Animated.createAnimatedComponent(LottieView);
Conclusion
Implementing Lottie in React and React Native is straightforward. The libraries are mature and well-documented. The API is consistent across platforms. With the optimizations I have shared, your animations will be smooth and performant.
The key is to start simple. Get the animation working. Then add control, interactivity, and optimizations. Use dotLottie for smaller files. Freeze offscreen animations. Use the right renderer for your use case.
Lottie transforms how you add motion to your React and React Native applications. It is a tool every developer should have in their toolkit.
Frequently Asked Questions
Can I use Lottie in React Native without native dependencies?
No. Lottie React Native requires native dependencies. The library uses the native Lottie libraries for iOS and Android.
What is the difference between lottie-react-native and lottie-web?
lottie-react-native is for React Native (mobile apps). It uses native rendering. lottie-web is for React (web applications). It renders in the browser.
How do I update the animation color dynamically in React Native?
You can use dotLottie with motion tokens. Define the color as a token in the dotLottie file. Then update the token value in your code.
Can I use Lottie with Expo?
Yes. Use the expo-lottie library for Expo projects. It provides a wrapper around lottie-react-native.
What is the best way to handle Lottie animations in a React Native list?
Use flatlist optimization techniques. Use the freezeOnOffscreen prop to stop rendering offscreen animations. Use smaller, simpler animations in lists.