# Compottie: rendering Lottie animations in Compose Multiplatform

> Compottie is a Compose Multiplatform library that renders Lottie animations with its own pure Kotlin rendering engine rather than platform delegates, with a lite build for smaller binaries and separate modules for dotLottie, network loading and resources. It suits a Kotlin Multiplatform team that wants one animation path across Android, iOS, JVM, macOS and web, and it is a poor fit if your animations rely on features the renderer does not implement.

**alexzhirkevich/compottie** — Compose Multiplatform library for rendering Lottie animations with a custom pure Kotlin renderer

- Repository: https://github.com/alexzhirkevich/compottie
- Stars: 697 · Forks: 27
- Language: Kotlin
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/alexzhirkevich-compottie

## A renderer written in Kotlin instead of delegating to the platform

Compottie is a Compose Multiplatform library for rendering Lottie animations, and the decision that shapes everything else is stated in the installation notes: starting from v2.0, Compottie has its own multiplatform rendering engine without any platform delegates.

That matters because the usual way to show a Lottie animation in a multiplatform app is to wrap a different implementation on each platform, the native one on Android and iOS and something else on the JVM and web. Each wrapper means a second API, a second set of behaviours and a second set of bugs. A single renderer written in Kotlin means one code path, and the differences between platforms are limited to what the Compose canvas itself can do.

The scale of the feature set is not hidden. The documentation points to a file, supported_features.md, listing the supported After Effects Lottie features, and there is a separate supported_expressions.md for expressions. That is the honest way to present a reimplementation, and it is the first thing to read before committing, because a Lottie file exported from After Effects can contain any feature the designer used.

The project carries the Lottie 1.0 compliance badge, and the topic list names bodymovin and after-effects, which is the export pipeline the format comes from. The licence is MIT, the primary language is Kotlin, and the default branch in this repository is standalone-main.

For a team already on Compose Multiplatform, the pitch is straightforward: one dependency, one API, and animations that look the same on every target.

## Five modules, and a lite build that halves the binary

The library is split into modules rather than shipped as one artifact, and the split is driven by what an app actually needs.

The main module, compottie, carries the rendering engine and the JsonString animation spec. compottie-lite is the same thing without expressions support, with about two times smaller binary size, which is a substantial saving when your animations do not use expressions. compottie-dot adds dotLottie and ZIP animation specs, so a compressed archive of assets can be loaded as one file. compottie-network adds the Url animation spec plus asset and font managers, built on Ktor3 with a local cache using Okio, which is what lets animations and their assets be fetched over the web. compottie-network-core holds base implementations that are free of the HTTP client, so you can plug in Ktor3 or any other client instead. compottie-resources adds the Resource animation spec with asset and font managers backed by Compose Multiplatform resources.

The dependency declarations look like this in a version catalog:

```toml
[versions]
compottie="<version>"

[libraries]
compottie = { module = "io.github.alexzhirkevich:compottie", version.ref = "compottie" }
compottie-lite = { module = "io.github.alexzhirkevich:compottie-lite", version.ref = "compottie" }
compottie-dot = { module = "io.github.alexzhirkevich:compottie-dot", version.ref = "compottie" }
```

The group is io.github.alexzhirkevich, and the artifacts are published to Maven Central, with a compatibility table mapping Compose Multiplatform versions to Compottie versions: 1.12 to the current release, 1.11 to 2.2.4, and 1.10 to 2.1.0.

One Android-specific note is easy to miss. For projects with a minSdk below 26, the dot and network modules require library desugaring, since they rely on Java APIs that are not present on older Android versions.

The repository layout mirrors the module structure, with a directory for each of compottie, compottie-lite, compottie-dot, compottie-network, compottie-network-core and compottie-resources, plus a compottie-core directory, and an example/ directory containing an androidApp, desktopApp, iosApp, webApp and a shared module.

## Rendering a composition, and driving its progress

The basic usage reads a JSON animation from resources, turns it into a composition, and paints it with a remembered painter:

```kotlin
val composition by rememberLottieComposition {
    LottieCompositionSpec.JsonString(
        Res.readBytes("files/anim.json").decodeToString()
    )
}
val progress by animateLottieCompositionAsState(composition)

Image(
    painter = rememberLottiePainter(
        composition = composition,
        progress = { progress },
    ),
    contentDescription = "Lottie animation"
)
```

Three pieces do the work. rememberLottieComposition produces a LottieComposition from a spec, and the spec is an open interface that lets you pick the source, whether that is a JSON string, a ZIP, a URL or a resource. animateLottieCompositionAsState is the animation driver, and it produces a progress value. rememberLottiePainter turns the composition and the progress into something the Image composable can draw.

There is also an overload of rememberLottiePainter that merges the painter and the animateLottieCompositionsState() call, if you would rather not hold the two apart.

The Resource spec requires the compottie-resources dependency, and using the Lottie composable rather than Image additionally gives you support for state machines, which the documentation links to a section of its own.

The composition object itself is worth understanding. A LottieComposition is the parsed version of the Lottie JSON file, it is stateless, and it can be cached and reused freely. The parsed form is separate from the animation state, which means an expensive parse can happen once and be shared across several painters, and that a composition survives a recomposition without being thrown away.

## Sources, and the difference between a painter and a composable

Because the spec is an open interface, the source of an animation is a choice rather than a fixed decision, and the library ships implementations for the common ones.

JsonString takes the animation as a string, which is what the basic example does by reading a file from Compose resources and decoding it. DotLottie takes the dotLottie container, and the dotLottie format is a ZIP of the animation and its assets, so the same spec covers both a JSON file and a packaged archive. Resource takes a URI from Compose Multiplatform resources, and that spec needs the compottie-resources module. Url takes a network location and arrives with the compottie-network module, which also brings the asset and font managers and the local cache.

The distinction between Image and Lottie is small but real. Image with a remembered painter is the straightforward path, and it is what most apps want. The Lottie composable is the richer one, and its extra capability is state machines, where an animation can move between named states rather than simply playing a timeline forward.

Fonts deserve a specific mention because they are where Lottie implementations usually get complicated. The animation can reference text layers with specific fonts, and the font manager is what resolves them. In the compottie-network module the font manager comes with the network support and caches what it fetches, and in compottie-resources the font manager is backed by Compose Multiplatform resources instead. A self-contained animation with no text layers needs neither.

The same split exists for assets generally. An animation that embeds images needs them resolved, and the asset managers in the network and resources modules are the two routes to that, one fetching and one reading from the bundle.

## Where Compottie is the wrong choice

The first limitation is coverage, and it is the one to check first. A Lottie file is an export of an After Effects composition, and it can contain any feature the designer used. Compottie implements a subset, listed in supported_features.md, and there is a separate file for expressions. If your animation uses a feature that is not in that list, the rendering will differ from the reference implementation, and the difference will be subtle rather than obvious, which is the worst way for it to fail. A team with a large library of animations produced by different designers should audit the files before switching, not after.

The second is expressions and the lite build. The full module supports expressions, and compottie-lite does not, in exchange for about half the binary size. That is a good trade for a team that knows its animations are expression-free, and a bad one to discover halfway through, since the failure appears as a static or wrongly posed frame rather than as a build error.

The third is that the pre-Compose Multiplatform 2.0 architecture is gone. The installation note says the platform delegates were removed, which is the right call for a multiplatform library and a real cost for anyone who was relying on the native renderer's edge cases or its performance characteristics. A pure Kotlin renderer is not the native renderer, and on a platform where the native implementation is highly tuned, the difference is worth measuring on a real device rather than assuming.

The fourth is the ecosystem of Lottie tooling that this library does not join. The Lottie format is widely used, but a Kotlin renderer that reimplements it is a reimplementation, and the tools around it, the web players, the design-time previews and the exporters, all describe a different implementation. A team that needs its animations to look identical to what a designer sees in a browser preview will find gaps.

The fifth is the version coupling to Compose Multiplatform. The compatibility table maps Compose Multiplatform versions to Compottie versions, so staying current with Compose Multiplatform means checking which Compottie release matches. The releases move quickly, with 2.3.1, 2.3.2 and 2.3.3 published in about a month.

## Conclusion

Compottie fits a Kotlin Multiplatform team whose apps need the same Lottie animations on Android, iOS, JVM, macOS and web, since the pure Kotlin renderer removes the per-platform delegate work and the module split lets you take only the pieces your app needs, with compottie-lite cutting the binary roughly in half when expressions are not needed. It is the wrong choice if your animations use expressions, since the lite build drops them and the full build implements only the features listed in supported_features.md, and it is the wrong choice for a single-platform app where the platform's own Lottie runtime is a better fit. Before adopting it, check supported_features.md and supported_expressions.md against the animations you actually ship, and confirm the Compose Multiplatform version you are on matches the compatibility table, since the last push was on 2026-10-09 with version 2.3.3 released on 2026-10-05.

## FAQ

### How do I add Compottie to a Compose Multiplatform project?

Add a Gradle dependency on io.github.alexzhirkevich:compottie, or one of the other modules, using the version that matches your Compose Multiplatform version from the compatibility table. For Android projects with a minSdk below 26, the dot and network modules require library desugaring.

### What is the difference between compottie and compottie-lite?

compottie-lite is the same library without expressions support, and has about two times smaller binary size. If your animations do not use expressions, the lite build is the better trade.

### Does Compottie need platform delegates?

No. The installation notes state that starting from v2.0 Compottie has its own multiplatform rendering engine without any platform delegates, and the list of supported After Effects Lottie features is in supported_features.md.

### How do I load a Lottie animation from the network with Compottie?

Add the compottie-network module, which contains the Url animation spec and asset and font managers built on Ktor3 with an Okio local cache. For a different HTTP client, compottie-network-core provides base implementations free of an HTTP client.

### What licence is Compottie released under?

MIT, with the licence file at the root of the repository.

## Sources

- [alexzhirkevich/compottie on GitHub](https://github.com/alexzhirkevich/compottie)
- [Issues](https://github.com/alexzhirkevich/compottie/issues)
- [License: MIT](https://github.com/alexzhirkevich/compottie/blob/standalone-main/LICENSE)
- [README](https://github.com/alexzhirkevich/compottie/blob/standalone-main/README.md)
- [Releases](https://github.com/alexzhirkevich/compottie/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/alexzhirkevich-compottie
