Lottie & dotLottie component for React Native (iOS, Android, and Web)
npm install @lottiefiles/dotlottie-react-nativeyarn add @lottiefiles/dotlottie-react-nativeTo support iOS 15.4, ensure your Podfile specifies the platform version:
platform :ios, '15.4'After installing the package, navigate to the ios directory and install the pods:
cd ios
pod installTo support .lottie files, update your metro.config.js:
// metro.config.js
const { getDefaultConfig } = require('metro-config');
module.exports = (async () => {
const {
resolver: { sourceExts, assetExts },
} = await getDefaultConfig();
return {
resolver: {
assetExts: [...assetExts, 'lottie'],
},
};
})();Expo projects must include the native binaries before this library can render animations. We ship a config plugin scaffold (withDotLottie) so Expo developers can prepare builds with minimal setup.
-
Add the plugin – the package already declares it under the
expo.pluginsfield, so it is applied automatically. To customize behaviour, you can reference it explicitly inapp.json:{ "expo": { "plugins": ["@lottiefiles/dotlottie-react-native/plugin"] } } -
Generate native projects – run
expo prebuild(or initialise a development build if you haven’t already):expo prebuild
-
Create a development build – install the native code with
expo run:ios/expo run:android, or your preferred EAS build workflow. Expo Go does not bundle the DotLottie native module.
Tip: this repository ships an Expo dev-client harness under
expo-example/. Use it to exercise the config plugin locally withyarn workspace dotlottie-react-native-expo-example prebuild.
If you must stay in Expo Go, fall back to the web implementation shipped in this package (or the underlying @lottiefiles/dotlottie-react) until a native build is available:
import { Platform } from 'react-native';
import { DotLottie as DotLottieNative } from '@lottiefiles/dotlottie-react-native';
import { DotLottie as DotLottieWeb } from '@lottiefiles/dotlottie-react';
export const DotLottie = Platform.select({
ios: DotLottieNative,
android: DotLottieNative,
default: DotLottieWeb,
});This keeps the API surface consistent while you work entirely in Expo Go. Once you produce a dev build, swap back to the native export everywhere or gate the fallback behind feature flags.
This package supports React Native Web out of the box. The web implementation uses @lottiefiles/dotlottie-react under the hood.
@lottiefiles/dotlottie-react-native now ships with a Legacy Interop bridge so the same component works on both Paper and Fabric. Paper remains the default on every platform, and you can opt-in to the new architecture per-app.
-
iOS: enable Fabric by turning on
RCT_NEW_ARCH_ENABLEDbefore runningpod install. For example:cd ios RCT_NEW_ARCH_ENABLED=1 bundle exec pod install
Clearing the flag (or setting it to
0) keeps the Paper manager in place. No changes are required to continue using Paper. -
Android: toggle the architecture by setting
newArchEnabled=trueinandroid/gradle.properties, or pass-PnewArchEnabled=true/false(orORG_GRADLE_PROJECT_newArchEnabled=...) on the Gradle command line.
The repository’s example app exposes Yarn scripts to exercise each mode:
yarn ios:paper # Paper build
yarn ios:fabric # Fabric build
yarn android:paper # Paper build
yarn android:fabric # Fabric buildUse the matching :build variants (for example, yarn ios:fabric:build) when you only need to compile instead of launching the simulator/emulator.
import { Button, StyleSheet, View } from 'react-native';
import { DotLottie, Mode, type Dotlottie } from '@lottiefiles/dotlottie-react-native';
import { useRef } from 'react';
export default function App() {
const ref = useRef<Dotlottie>(null);
return (
<View style={styles.container}>
<DotLottie
ref={ref}
source={require('../assets/animation.lottie')}
style={styles.box}
loop={false}
autoplay={false}
/>
<Button title="Play" onPress={() => ref.current?.play()} />
<Button title="Pause" onPress={() => ref.current?.pause()} />
<Button title="Stop" onPress={() => ref.current?.stop()} />
<Button title="Loop" onPress={() => ref.current?.setLoop(true)} />
<Button title="Speed" onPress={() => ref.current?.setSpeed(1)} />
<Button
title="FORWARD"
onPress={() => ref.current?.setPlayMode(Mode.FORWARD)}
/>
<Button
title="REVERSE"
onPress={() => ref.current?.setPlayMode(Mode.REVERSE)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
box: {
width: 200,
height: 200,
marginVertical: 20,
},
});| Prop | Type | Default Value | Description |
|---|---|---|---|
source |
string | { uri: string } |
Required | Specifies the animation file to be loaded (local or remote URL). |
style |
ViewStyle |
undefined |
Custom styles for the animation container. |
loop |
boolean |
false |
Determines if the animation should loop continuously. |
autoplay |
boolean |
false |
Determines if the animation should start playing automatically. |
speed |
number |
1.0 |
The playback speed of the animation (e.g., 0.5, 1, 2). |
playMode |
Mode |
FORWARD |
The play mode: FORWARD, REVERSE, BOUNCE, REVERSE_BOUNCE. |
useFrameInterpolation |
boolean |
false |
Enables frame interpolation for smoother animations. |
segment |
[number, number] |
undefined |
Specifies a segment of the animation to play [startFrame, endFrame]. |
marker |
string |
undefined |
Specifies a marker to use for playback. |
themeId |
string |
undefined |
The theme ID to apply to the animation. |
stateMachineId |
string |
undefined |
The ID of the state machine to load and start automatically. |
Access these methods via a ref:
const ref = useRef<Dotlottie>(null);
ref.current?.play();| Method | Description |
|---|---|
play() |
Starts playing the animation. |
pause() |
Pauses the animation. |
stop() |
Stops the animation and resets to the beginning. |
setLoop(loop: boolean) |
Sets the looping behavior of the animation. |
setSpeed(speed: number) |
Sets the playback speed of the animation. |
setPlayMode(mode: Mode) |
Sets the play mode of the animation. |
setFrame(frame: number) |
Sets the current frame of the animation. |
freeze() |
Freezes the animation at the current frame. |
unfreeze() |
Unfreezes the animation. |
resize(width: number, height: number) |
Resizes the animation viewport. |
setSegment(start: number, end: number) |
Sets a segment of the animation to play. |
setMarker(marker: string) |
Sets a marker for playback. |
setTheme(themeId: string) |
Applies a theme to the animation. |
loadAnimation(animationId: string) |
Loads a specific animation by ID. |
stateMachineStart() |
Starts the state machine. |
stateMachineStop() |
Stops the state machine. |
stateMachineLoad(stateMachineId: string) |
Loads a state machine by ID. |
stateMachineFire(event: string) |
Fires an event in the state machine. |
stateMachineSetNumericInput(key: string, value: number) |
Sets a numeric input value in the state machine. |
stateMachineSetStringInput(key: string, value: string) |
Sets a string input value in the state machine. |
stateMachineSetBooleanInput(key: string, value: boolean) |
Sets a boolean input value in the state machine. |
| Event | Description |
|---|---|
onLoad?: () => void |
Called when the animation is loaded. |
onComplete?: () => void |
Called when the animation completes. |
onLoadError?: () => void |
Called when there's an error loading the animation. |
onPlay?: () => void |
Called when the animation starts playing. |
onPause?: () => void |
Called when the animation is paused. |
onStop?: () => void |
Called when the animation is stopped. |
onLoop?: (loopCount: number) => void |
Called when the animation loops, with the current loop count. |
onFrame?: (frameNo: number) => void |
Called on each frame update. |
onRender?: (frameNo: number) => void |
Called when a frame is rendered. |
onFreeze?: () => void |
Called when the animation is frozen. |
onUnFreeze?: () => void |
Called when the animation is unfrozen. |
onDestroy?: () => void |
Called when the animation is destroyed. |
| Event | Description |
|---|---|
onStateMachineStart?: () => void |
Called when the state machine starts. |
onStateMachineStop?: () => void |
Called when the state machine stops. |
onStateMachineStateEntered?: (enteringState: string) => void |
Called when entering a new state. |
onStateMachineStateExit?: (leavingState: string) => void |
Called when exiting a state. |
onStateMachineTransition?: (previousState: string, newState: string) => void |
Called during a state transition. |
onStateMachineBooleanInputChange?: (inputName: string, oldValue: boolean, newValue: boolean) => void |
Called when a boolean input changes. |
onStateMachineNumericInputChange?: (inputName: string, oldValue: number, newValue: number) => void |
Called when a numeric input changes. |
onStateMachineStringInputChange?: (inputName: string, oldValue: string, newValue: string) => void |
Called when a string input changes. |
onStateMachineInputFired?: (inputName: string) => void |
Called when an input event is fired. |
onStateMachineCustomEvent?: (message: string) => void |
Called when a custom state machine event occurs. |
onStateMachineError?: (message: string) => void |
Called when a state machine error occurs. |
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
Made with create-react-native-library