Skip to main content
Lottie4 min readNovember 2026

How do I know when a Lottie animation has completed?

Short answer

Listen for the player's complete event. In lottie-web use anim.addEventListener('complete', fn); in lottie-react use the onComplete prop; on Android add an Animator listener and use onAnimationEnd; on iOS pass a completion closure to play(). Looping animations never complete, so listen for the loop event instead.

Core Takeaway

  • lottie-web: "complete" fires when a non-looping animation ends
  • Looping animations fire "loopComplete" on each loop instead
  • lottie-react: onComplete and onLoopComplete props
  • Android: addAnimatorListener, onAnimationEnd
  • iOS: animationView.play { finished in ... }

This is the most upvoted Lottie question on Stack Overflow. The usual mistake is listening for complete on an animation that has loop set to true, which never ends.

lottie-web (plain JavaScript)

import lottie from 'lottie-web';

const anim = lottie.loadAnimation({
  container: document.getElementById('checkmark'),
  renderer: 'svg',
  loop: false,
  autoplay: true,
  path: '/animations/checkmark.json'
});

anim.addEventListener('complete', () => {
  console.log('done');
});

// for looping animations
anim.addEventListener('loopComplete', () => {});

React (lottie-react)

import Lottie from 'lottie-react';
import checkmark from './checkmark.json';

<Lottie
  animationData={checkmark}
  loop={false}
  onComplete={() => setShowNext(true)}
/>

dotLottie web

dotLottie.addEventListener('complete', () => {});

Android and iOS

On Android with the View system, call animationView.addAnimatorListener and handle onAnimationEnd. In Jetpack Compose, read the progress from animateLottieCompositionAsState and react when it reaches 1f. On iOS with lottie-ios, call animationView.play { finished in } and check that finished is true, because it is false when the animation was interrupted.

If you find yourself chaining many completion handlers to move between states (play intro, then idle, then success), that is a state machine written by hand. Tools with built-in state machines, such as dotLottie state machines, Rive or ExodeUI, can hold that logic in the file. We make ExodeUI.

Frequently asked questions

Why does my Lottie complete event never fire?

The animation is probably set to loop. Set loop to false, or listen for loopComplete instead.

Does complete fire when I call stop()?

No. complete fires when playback reaches the end on its own. Run your own logic where you call stop().

How do I run code at a specific frame?

In lottie-web, listen for enterFrame and check anim.currentFrame, or split the animation into segments with playSegments.

Is there a completion callback in Lottie for Flutter?

Yes. With the lottie package you pass your own AnimationController and listen for AnimationStatus.completed.

Related Guides & Examples

Put the sequence in the file

Model intro, idle and success as states in ExodeUI, then fire one trigger from your code.

Learn about state machines
ExodeUI

EXODEUI DESKTOP

A little space for good ideas.

Choose your platform to get the official ExodeUI installer.

Looking for Intel Mac or other builds? Explore the web studio or check all download options.

Prefer the browser? Try for free in your browser →