RepoPilotOpen in app →

airbnb/lottie-android

Render After Effects animations natively on Android and iOS, Web, and React Native

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 3mo ago
  • 28+ active contributors
  • Distributed ownership (top contributor 42% of recent commits)
Show all 6 evidence items →
  • Apache-2.0 licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/airbnb/lottie-android)](https://repopilot.app/r/airbnb/lottie-android)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/airbnb/lottie-android on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: airbnb/lottie-android

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/airbnb/lottie-android shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 3mo ago
  • 28+ active contributors
  • Distributed ownership (top contributor 42% of recent commits)
  • Apache-2.0 licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live airbnb/lottie-android repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/airbnb/lottie-android.

What it runs against: a local clone of airbnb/lottie-android — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in airbnb/lottie-android | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 111 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>airbnb/lottie-android</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of airbnb/lottie-android. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/airbnb/lottie-android.git
#   cd lottie-android
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of airbnb/lottie-android and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "airbnb/lottie-android(\\.git)?\\b" \\
  && ok "origin remote is airbnb/lottie-android" \\
  || miss "origin remote is not airbnb/lottie-android (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java" \\
  && ok "lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java" \\
  || miss "missing critical file: lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java"
test -f "lottie/src/main/java/com/airbnb/lottie/LottieComposition.java" \\
  && ok "lottie/src/main/java/com/airbnb/lottie/LottieComposition.java" \\
  || miss "missing critical file: lottie/src/main/java/com/airbnb/lottie/LottieComposition.java"
test -f "lottie/src/main/java/com/airbnb/lottie/parser/LottieParser.java" \\
  && ok "lottie/src/main/java/com/airbnb/lottie/parser/LottieParser.java" \\
  || miss "missing critical file: lottie/src/main/java/com/airbnb/lottie/parser/LottieParser.java"
test -f "lottie/src/main/java/com/airbnb/lottie/animation/LottieValueAnimator.java" \\
  && ok "lottie/src/main/java/com/airbnb/lottie/animation/LottieValueAnimator.java" \\
  || miss "missing critical file: lottie/src/main/java/com/airbnb/lottie/animation/LottieValueAnimator.java"
test -f "lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java" \\
  && ok "lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java" \\
  || miss "missing critical file: lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 111 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~81d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/airbnb/lottie-android"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Lottie for Android is a library that parses Adobe After Effects animations exported as JSON (via Bodymovin) and renders them natively on Android without hand-coded recreation. It enables designers to export animations directly from After Effects and ship them in Android apps as lightweight JSON files rather than video or frame sequences. The core capability is real-time vector animation rendering on mobile with support for complex features like masks, track mattes, shape layers, and dynamic gradients. Multi-module Android project structure: core library in lottie/ (Java 927k LOC, Kotlin 381k LOC), Compose wrapper in lottie-compose/ for Jetpack Compose, benchmark app in benchmark-app/, and extensive sample animations in 'After Effects Samples/' directory with test cases (KeyPath.aep, MatteMask.aep, etc.). CI configuration in .github/workflows/. Code style and inspection rules in .idea/ directories indicate strict quality gates.

👥Who it's for

Android developers and designers collaborating on animation-heavy apps. Designers use After Effects to create animations, designers/engineers export via Bodymovin plugin, and Android engineers integrate the JSON into their apps using the Lottie library. Used at scale by companies like Airbnb, Coinbase, and Stream who need polished, designer-authored animations without rebuilding in code.

🌱Maturity & risk

Production-ready and actively maintained. The repo has 31.5k+ stars, clear release processes (RELEASE.md, CHANGELOG.md versioning), CI/CD via GitHub Actions (validate.yml), and support across multiple platforms (iOS, Web, React Native, Windows). Recent activity visible in benchmark and Compose support additions indicates ongoing active development, not maintenance mode.

Standard open source risks apply.

Active areas of work

Active development on Jetpack Compose support (evidenced by CHANGELOG_COMPOSE.md, Compose plugin configuration in benchmark build.gradle, lottie-compose module). Baseline profiling and performance benchmarking being added (benchmark-app with androidx.baselineprofile). Validation pipeline running on commits (validate.yml GitHub Action). Recent updates suggest focus on modern Android development patterns and performance optimization.

🚀Get running

git clone https://github.com/airbnb/lottie-android.git
cd lottie-android
# Build using Gradle (Android Studio project structure)
./gradlew build
# Run sample app or benchmark
./gradlew :sample:run  # if sample module exists
./gradlew :benchmark-app:assemble

Daily commands: No traditional dev server. To develop: (1) Open in Android Studio, (2) Build library via ./gradlew :lottie:build, (3) Run unit tests via ./gradlew test, (4) Install sample app via ./gradlew :sample:installDebug && adb shell am start ..., (5) View instrumented tests via ./gradlew connectedAndroidTest. CI validation runs via GitHub Actions on push (see validate.yml).

🗺️Map of the codebase

  • lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java — Main entry point for rendering Lottie animations on Android; all animation lifecycle and property binding flows through this view component
  • lottie/src/main/java/com/airbnb/lottie/LottieComposition.java — Core data structure representing a parsed After Effects animation; contains all animation metadata, layers, and keyframes required for rendering
  • lottie/src/main/java/com/airbnb/lottie/parser/LottieParser.java — Parses JSON exported by Bodymovin from After Effects into LottieComposition objects; critical for animation loading pipeline
  • lottie/src/main/java/com/airbnb/lottie/animation/LottieValueAnimator.java — Drives animation playback with frame-by-frame timing and progress callbacks; orchestrates the animation loop
  • lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java — Drawable responsible for rendering animation frames to Canvas; bridges animation state to Android rendering system
  • build.gradle — Root Gradle build configuration; defines dependencies, Kotlin version, and compilation settings across all modules
  • CHANGELOG.md — Comprehensive history of API changes and breaking updates; essential for understanding version compatibility and migration paths

🛠️How to make changes

Add a new shape type or rendering feature

  1. Create a new ContentModel subclass in lottie/src/main/java/com/airbnb/lottie/model/content/ representing your shape type (e.g., Star.java) (lottie/src/main/java/com/airbnb/lottie/model/content/)
  2. Create a parser in lottie/src/main/java/com/airbnb/lottie/parser/content/ to deserialize from Bodymovin JSON (e.g., StarParser.java) (lottie/src/main/java/com/airbnb/lottie/parser/content/)
  3. Create an animation content class in lottie/src/main/java/com/airbnb/lottie/animation/content/ that renders to Canvas (e.g., StarContent.java) (lottie/src/main/java/com/airbnb/lottie/animation/content/)
  4. Register your parser in ShapeLayerParser.java by adding a case in the content type switch statement (lottie/src/main/java/com/airbnb/lottie/parser/ShapeLayerParser.java)
  5. Add test After Effects sample in After Effects Samples/ and reference in sample app (After Effects Samples/)

Add a new dynamic property callback for runtime modification

  1. Identify the keyframe animation class handling your property in lottie/src/main/java/com/airbnb/lottie/animation/keyframe/ (lottie/src/main/java/com/airbnb/lottie/animation/keyframe/)
  2. Define a new PropertyValuesHolder or LottieValueCallback subclass in lottie/src/main/java/com/airbnb/lottie/value/ (lottie/src/main/java/com/airbnb/lottie/value/)
  3. Add a setValueCallback() method to LottieAnimationView.java that associates your callback with a KeyPath (lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java)
  4. Update the keyframe animation class to query and apply your callback during getValue() interpolation (lottie/src/main/java/com/airbnb/lottie/animation/keyframe/BaseKeyframeAnimation.java)

Add support for a new animation property from After Effects

  1. Create an AnimatableValue or AnimatableProperty subclass in lottie/src/main/java/com/airbnb/lottie/model/animatable/ (lottie/src/main/java/com/airbnb/lottie/model/animatable/)
  2. Add parser logic in the relevant LayerParser (e.g., ShapeLayerParser.java) to extract your property from JSON (lottie/src/main/java/com/airbnb/lottie/parser/)
  3. Create a KeyframeAnimation subclass in lottie/src/main/java/com/airbnb/lottie/animation/keyframe/ for interpolation (lottie/src/main/java/com/airbnb/lottie/animation/keyframe/)
  4. Update the content rendering class (e.g., ShapeContent.java or FillContent.java) to apply your animated property during draw() (lottie/src/main/java/com/airbnb/lottie/animation/content/)
  5. Add a sample After Effects animation in After Effects Samples/Test/ and validate rendering (After Effects Samples/Test/)

Add a new Compose composable wrapper

  1. Create a new Kotlin file in lottie-compose/src/main/java/com/airbnb/lottie/compose/ for your composable (lottie-compose/src/main/java/com/airbnb/lottie/compose/)
  2. Use LottieAnimation.kt as a reference for state management and rememberLottieComposition() patterns (lottie-compose/src/main/java/com/airbnb/lottie/compose/LottieAnimation.kt)
  3. Add preview functions annotated with @Preview in your file for quick preview in Android Studio (lottie-compose/src/main/java/com/airbnb/lottie/compose/)
  4. Update sample-compose/build.gradle if adding new dependencies (sample-compose/build.gradle)

🪤Traps & gotchas

(1) Bodymovin version alignment: Animations exported with newer Bodymovin may use JSON schema features older Lottie versions don't support—check CHANGELOG for breaking changes. (2) Canvas rendering limitations: Some complex AE features (certain blend modes, advanced effect parameters) may not render identically to AE; test visual fidelity with actual AEP files. (3) Memory usage with large animations: High-resolution image assets embedded in JSON can bloat file size and RAM—Lottie doesn't auto-downscale; designers must optimize. (4) compileSdk 36 requirement: The benchmark-app uses compileSdk 36, so Android API level changes may affect compatibility. (5) No built-in SVG support: Only Bodymovin JSON—other vector formats need conversion first.

💡Concepts to learn

  • Bodymovin JSON Schema — Lottie is fundamentally a parser and renderer of this specific JSON format exported from After Effects; understanding the schema (layers, keyframes, properties, expressions) is essential to debug parsing issues and extend feature support
  • Keyframe Interpolation & Easing Functions — Animation smoothness depends on correctly interpolating values between keyframes with the right easing curve (linear, ease-in, bezier, etc.); After Effects supports complex easing that Lottie must replicate
  • Layer Composition & Nesting — Lottie animations use hierarchical layer trees with parent-child relationships, masks, and blend modes; rendering requires depth-first traversal and canvas state management
  • Track Mattes & Clipping Masks — A complex After Effects feature where one layer's alpha/luminance masks another layer's visibility; Lottie must implement via canvas clipping or off-screen buffering (seen extensively in test files like MatteMask.aep)
  • Vector Shape Rendering (Bezier Curves) — Shape layers in AE are defined by bezier paths; Lottie must convert them to Android Path objects and render via Canvas, supporting dynamic manipulation of control points via keyframes
  • Frame-Based Animation Loop & Timing — Lottie manages animation playback by stepping through discrete frames at a target framerate; requires precise timing, progress tracking, and frame-skipping under load (relevant to benchmark-app)
  • Property Binding & Keypath Expressions — Lottie supports dynamic property override via keypaths (e.g., targeting a specific shape's fill color at runtime); enables interactive animations and A/B testing without re-exporting from AE (seen in Test/KeyPath.aep)
  • airbnb/lottie-ios — Official Lottie implementation for iOS—same animation format, shared Bodymovin compatibility, developers often need cross-platform consistency
  • airbnb/lottie-web — Official Lottie for web browsers—JavaScript/Canvas-based rendering of same JSON format, used for web-based animation previews and deployment
  • airbnb/lottie-react-native — React Native bridge to native Lottie (both iOS and Android)—allows shared animation code across mobile and web in React-based apps
  • bodymovin/bodymovin — The After Effects plugin that exports animations to Lottie JSON format—understanding its output structure is essential for debugging animation import issues
  • microsoft/Lottie-Windows — Microsoft's Windows implementation of Lottie—extends cross-platform animation ecosystem and shares same JSON specification

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for lottie-compose module

The app-benchmark module depends on lottie-compose, but there's no visible test directory structure for the Compose integration layer. This is critical for a library that's actively maintained across multiple platforms. Unit tests would ensure Compose-specific rendering, animation state management, and Compose runtime integration work correctly across Android API levels.

  • [ ] Create src/test/kotlin and src/androidTest/kotlin directories in lottie-compose module
  • [ ] Add tests for Compose state hoisting (animation progress, play/pause state)
  • [ ] Add tests for LottieAnimation composable parameter combinations
  • [ ] Add instrumented tests verifying frame rendering matches core lottie-android output
  • [ ] Reference existing test patterns from main lottie module and adapt for Compose

Create GitHub Actions workflow for automated AEP-to-JSON export validation

The repo contains 15+ After Effects sample files (.aep) in 'After Effects Samples/' directory used for testing/demonstrations, but there's no CI validation that these files properly export to valid JSON via Bodymovin. A new workflow could catch export regressions and ensure sample files remain valid for contributors and users.

  • [ ] Create .github/workflows/validate-aep-exports.yml workflow
  • [ ] Add step to validate all .aep files in 'After Effects Samples/' export to valid JSON (can use aeftemplates or similar tooling)
  • [ ] Cross-reference exported JSONs against existing test fixture JSON files to detect format changes
  • [ ] Document in DESIGNER_NOTES.md how designers should validate exports before committing .aep changes
  • [ ] Make workflow run on PRs modifying .aep files or on schedule (weekly)

Add baseline rendering regression tests with golden images for core features

The repo has example AEP files for specific features (Masks.aep, Skew.aep, TrackMattes.aep, etc.) but no visible CI pipeline validating that rendering output matches expected golden images. This prevents visual regressions and is critical for a rendering library. A screenshot comparison test would catch subtle rendering bugs early.

  • [ ] Create app-golden-tests module (similar to app-benchmark) to render core feature animations
  • [ ] Use Jetpack Compose UI testing framework to capture LottieAnimation output for each major feature
  • [ ] Store golden PNG references in /app-golden-tests/src/test/resources/golden/ matching test names
  • [ ] Create GitHub Actions workflow running pixel-diff comparison (using tools like skiko or pixelmatch)
  • [ ] Document in DESIGNER_NOTES.md which AEP samples are used for regression testing

🌿Good first issues

  • Add Kotlin tests for the parser module (lottie/src/main/java/com/airbnb/lottie/parser/) converting them from Java—improves type safety and idiomatic Kotlin coverage for the JSON deserialization logic.
  • Extend After Effects Samples/Test/ with a new test AEP file for 'DynamicText' animations (point text with animated content) and add corresponding snapshot test—current samples cover shapes/masks but text animation coverage is sparse.
  • Document the LottieComposition model structure and keyframe interpolation algorithm in DESIGNER_NOTES.md with diagrams—current file focuses on design usage, not internal architecture that contributors need to understand.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 05ea92e — Support Lottie to be rendered on per-window UI thread (#2685) (fengjial-google)
  • c8addcb — v6.7.1 (allenchen1154)
  • 05ee1c1 — Safeguard against very large Bitmap creation (#2662) (allenchen1154)
  • 90f9f03 — v6.7.0 (gpeal)
  • 9c35bb5 — Optimize and improve performance of 3d layers (#2673) (hepiao3)
  • 82f1b17 — Add 3D rotation support for Lottie animations (#2666) (hepiao3)
  • c0a7e07 — v6.6.10 (allenchen1154)
  • 3ac73ed — Add RTL support to lottie-android (#2663) (nrchan)
  • c920e87 — Make lottieComposition public (#2660) (thebehera)
  • 5af8c29 — v6.6.10-SNAPSHOT (allenchen1154)

🔒Security observations

The codebase demonstrates moderate security posture with several notable concerns. The most critical issue is the use of debug signing credentials in the release build, which severely compromises application integrity and authenticity. Additionally, minification is disabled in the release build, exposing the code to reverse engineering. The benchmark build configuration lacks explicit security settings. The project itself (Lottie) is a well-maintained animation library with good community support, but this particular build configuration requires remediation. No hardcoded secrets, injection vulnerabilities, or Docker issues were identified in the provided files. The application targets modern Android versions (SDK 36) which is positive for security.

  • High · Debug Signing Config Used in Release Build — app-benchmark/build.gradle - release buildType configuration. The release build type is configured to use the debug signing config (signingConfig = signingConfigs.debug). This means the release APK would be signed with debug credentials, which are publicly known and compromise the security of the application. Debug-signed APKs can be easily repackaged and resigned by attackers. Fix: Configure a proper release signing config with secure credentials stored outside the repository. Use Android Studio's key management or environment variables to manage signing certificates securely.
  • Medium · Debuggable False Only in Release, Not in Benchmark Build — app-benchmark/build.gradle - benchmark buildType configuration. The benchmark build type is created by copying from release configuration, but explicitly sets signingConfig to debug. The debuggable flag is not explicitly set for the benchmark build, which may inherit it from release (false) or default to true, potentially allowing debugging of the benchmark variant. Fix: Explicitly set 'debuggable false' for the benchmark build type to prevent debugging capabilities in production-like builds.
  • Medium · Minify Disabled in Release Build — app-benchmark/build.gradle - release buildType configuration. The release build has minifyEnabled set to false. This means the APK is not obfuscated, making it easier for attackers to reverse engineer the code, understand the application logic, and identify potential security vulnerabilities. Fix: Enable minification by setting minifyEnabled to true and provide a proper proguard-rules.pro file. Keep the mapping file secure for debugging purposes.
  • Low · High Target SDK with Potential Permission Model Changes — app-benchmark/build.gradle - targetSdk configuration. The application targets SDK 36 (Android 15), which introduces new privacy and security changes. While this is generally positive, it requires careful handling of runtime permissions and scoped storage. Fix: Review Android 15+ privacy changes and ensure the application properly handles scoped storage, approximate location permissions, and other privacy-related features.
  • Low · Minimum SDK 21 is Dated — app-benchmark/build.gradle - minSdk configuration. minSdk 21 (Android 5.0 Lollipop, 2014) supports very old Android versions. This increases the attack surface and may include devices with unpatched security vulnerabilities. Fix: Consider raising minSdk to at least 24 (Android 7.0) or higher to reduce the attack surface and enable use of modern security APIs.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · airbnb/lottie-android — RepoPilot