{"id":14530599,"url":"https://github.com/alexzhirkevich/compottie","last_synced_at":"2026-01-11T16:53:54.824Z","repository":{"id":212106126,"uuid":"730724501","full_name":"alexzhirkevich/compottie","owner":"alexzhirkevich","description":"Compose Multiplatform library for rendering Lottie animations with custom pure Kotlin renderer","archived":false,"fork":false,"pushed_at":"2025-08-25T07:42:56.000Z","size":15864,"stargazers_count":458,"open_issues_count":5,"forks_count":17,"subscribers_count":3,"default_branch":"standalone-main","last_synced_at":"2025-08-25T09:57:02.114Z","etag":null,"topics":["after-effects","animation","bodymovin","compose","compose-multiplatform","kotlin","lottie","lottie-animation","lottie-compose"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexzhirkevich.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"supported_expressions.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-12-12T14:36:36.000Z","updated_at":"2025-08-25T07:43:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"a72afc25-82c7-4f7a-9760-8e559e20120f","html_url":"https://github.com/alexzhirkevich/compottie","commit_stats":null,"previous_names":["alexzhirkevich/compottie"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/alexzhirkevich/compottie","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexzhirkevich%2Fcompottie","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexzhirkevich%2Fcompottie/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexzhirkevich%2Fcompottie/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexzhirkevich%2Fcompottie/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexzhirkevich","download_url":"https://codeload.github.com/alexzhirkevich/compottie/tar.gz/refs/heads/standalone-main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexzhirkevich%2Fcompottie/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272913105,"owners_count":25014208,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["after-effects","animation","bodymovin","compose","compose-multiplatform","kotlin","lottie","lottie-animation","lottie-compose"],"created_at":"2024-09-05T00:01:08.437Z","updated_at":"2026-01-11T16:53:54.817Z","avatar_url":"https://github.com/alexzhirkevich.png","language":"Kotlin","funding_links":[],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"readme":"# Compottie\n\u003ca href=\"https://lottie.github.io/lottie-spec/1.0/\"\u003e\u003cimg width=\"144\" height=\"56\" alt=\"image\" src=\"https://lottie.github.io/compliance-buttons/lottie-1.0-light.svg\" /\u003e\u003c/a\u003e\n\nCompose Multiplatform library for rendering Lottie animations\n\n![badge-Android](https://img.shields.io/badge/Platform-Android-brightgreen)\n![badge-iOS](https://img.shields.io/badge/Platform-iOS-lightgray)\n![badge-JVM](https://img.shields.io/badge/Platform-JVM-orange)\n![badge-macOS](https://img.shields.io/badge/Platform-macOS-purple)\n![badge-web](https://img.shields.io/badge/Platform-Web-blue)\n\n\n![Example](https://github.com/alexzhirkevich/compottie/assets/63979218/2735c77a-d940-4fd7-825c-208454b3960a)\n\n# Installation\n\n\u003e [!IMPORTANT]\n\u003e Starting from v2.0 Compottie has its own multiplatform rendering engine without any platform delegates.\n\u003e \u003cbr\u003eList of supported AE Lottie features can be found [here](/supported_features.md)\n\n|          Module          | Description                                                                                                                                                                                                                                                                                          | \n|:------------------------:|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| \n|       `compottie`        | Main module with rendering engine and `JsonString` animation spec.                                                     |\n|     `compottie-lite`     | The same as `compottie`, but without expressions support. Has about 2 times smaller binary size.                                                                                                                                                                                                        |                                                                                                                                                                                                       |                                                                                                                                                                                                                                                                                |\n|     `compottie-dot`      | Contains [dotLottie](https://dotlottie.io/) and ZIP animation spec.                                                                                                                                                                                                        |\n|   `compottie-network`    | Contains `Url` animation spec and asset/font managers (with [Ktor3](https://ktor.io/) and local cache with [Okio](https://square.github.io/okio/)). Allows loading animations and assets from web.                                                                        |\n| `compottie-network-core` | Contains base HttpClient-free implementations for `network` module. Allows to specify custom HTTP client (Ktor3 or any other).                                                                                                                                                                       |\n|  `compottie-resources`   | Contains asset and font managers powered by official Compose resources. | \n\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.alexzhirkevich/compottie)](https://central.sonatype.com/artifact/io.github.alexzhirkevich/compottie)\n\nAdd as a Gradle dependency\n```toml\n[versions]\ncompottie=\"\u003cversion\u003e\"\n\n[libraries]\ncompottie = { module = \"io.github.alexzhirkevich:compottie\", version.ref = \"compottie\" }\ncompottie-lite = { module = \"io.github.alexzhirkevich:compottie-lite\", version.ref = \"compottie\" }\ncompottie-dot = { module = \"io.github.alexzhirkevich:compottie-dot\", version.ref = \"compottie\" }\ncompottie-network = { module = \"io.github.alexzhirkevich:compottie-network\", version.ref = \"compottie\" }\ncompottie-resources = { module = \"io.github.alexzhirkevich:compottie-resources\", version.ref = \"compottie\" }\n```\n\n\u003e [!NOTE]\nFor projects with Android minSdk \u003c 26 `dot` and `network` modules require [desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring)\n\n# Usage\n\n- [Basic Usage](#basic-usage)\n- [LottieComposition](#lottiecomposition)\n- [Animating/Updating Progress](#animatingupdating-progress)\n- [LottieAnimatable](#lottieanimatable)\n- [dotLottie (ZIP)](#dotlottie-zip)\n- [Images](#images)\n- [Fonts](#fonts)\n- [URL loading](#url-loading)\n- [Dynamic Properties](#dynamic-properties)\n\n\n## Basic Usage\n```kotlin\nval composition by rememberLottieComposition {\n    LottieCompositionSpec.JsonString(\n        Res.readBytes(\"files/anim.json\").decodeToString()\n    )\n}\nval progress by animateLottieCompositionAsState(composition)\n\nImage(\n    painter = rememberLottiePainter(\n        composition = composition,\n        progress = { progress },\n    ),\n    contentDescription = \"Lottie animation\"\n)\n```\nOr with the `rememberLottiePainter` overload that merges `rememberLottiePainter` and `animateLottieCompositionsState()`\n```kotlin\nval composition by rememberLottieComposition {\n    LottieCompositionSpec.JsonString(\n        Res.readBytes(\"files/anim.json\").decodeToString()\n    )\n}\n\nImage(\n    painter = rememberLottiePainter(\n        composition = composition,\n        iterations = Compottie.IterateForever\n    ),\n    contentDescription = \"Lottie animation\"\n)\n```\n\n## LottieComposition\n`LottieComposition` is the parsed version of your Lottie json file. It is stateless and can be \ncached/reused freely. Call `rememberLottieComposition(spec)` to create new composition. \n`LottieCompositionSpec` is an open interface that lets you select the animation source (string/zip, network/assets, etc.).\n\nFor example:\n```kotlin\nval animFromJsonRes by rememberLottieComposition {\n    LottieCompositionSpec.JsonString(\n        Res.readBytes(\"files/anim.json\").decodeToString()\n    )\n}\n\nval animFromUrl by rememberLottieComposition {\n    LottieCompositionSpec.Url(\"https://example.com/anim.lotie\")\n}\n\nval animFromArchiveRes by rememberLottieComposition {\n    LottieCompositionSpec.DotLottie(\n        Res.readBytes(\"files/anim.lottie\")\n    )\n}\n```\n\nThe type returned from `rememberLottieComposition` is\n```kotlin\ninterface LottieCompositionResult : State\u003cLottieComposition?\u003e\n```\nThis allows you to use it in two ways:\n```kotlin\nval composition: LottieComposition? by rememberLottieComposition(spec)\n```\nThis will return null until the composition is parsed and then will return the `LottieComposition` object.\nUse this version in most cases, especially if you don't need any of the extra functionality on `LottieCompositionResult`.\n\n```kotlin\nval compositionResult: LottieCompositionResult = rememberLottieComposition(spec)\n```\n`LottieCompositionResult` lets you:\n1. Access the composition via `compositionResult.value`\n2. Access `error`, `isLoading`, `isComplete`, `isFailure`, and `isSuccess` properties.\n3. Call `await()` to await the parsed composition from a coroutine.\n\n## Animating/Updating Progress\n\nYou have the option of handling progress entirely yourself. If you choose to do that, just pass in `progress` to your `LottieAnimation` composable.\n\nIn most cases, you will want to use either `animateLottieCompositionAsState()` or `LottieAnimatable`. These APIs were designed to be analogous to the standard Jetpack Compose APIs. `animateLottieCompositionAsState` is analogous to [animate*AsState](https://developer.android.com/jetpack/compose/animation#animatable) and `LottieAnimatable` is analogous to [Animatable](https://developer.android.com/jetpack/compose/animation#animatable).\n\nThe decision for whether to use one over the other is similar as well:\n* If your animation is very simple or a function of other state properties, use `animateLottieCompositionAsState()`.\n* If you need to imperatively call `animate` or `snapTo` from something like a `LaunchedEffect` then use `LottieAnimatable`.\n\n`animateLottieCompositionAsState()` returns and `LottieAnimatable` implements:\n```kotlin\ninterface LottieAnimationState : State\u003cFloat\u003e\n```\n\n### animateLottieCompositionAsState()\n```kotlin\nval progress by animateLottieCompositionAsState(composition)\n```\n```kotlin\nval progress by animateLottieCompositionAsState(\n    composition,\n    iterations = Compottie.IterateForever,\n)\n```\n```kotlin\nval progress by animateLottieCompositionAsState(\n    composition,\n    clipSpec = LottieClipSpec.Progress(0.5f, 0.75f),\n)\n```\n\n### LottieAnimatable\n```kotlin\n@Stable\nclass MyHoistedState {\n    val lottieAnimatable = LottieAnimatable()\n    val somethingElse by mutableStateOf(0f)\n}\n```\n```kotlin\nval composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.animation))\nval lottieAnimatable = rememberLottieAnimatable()\nLaunchedEffect(Unit) {\n    lottieAnimatable.animate(\n        composition,\n        iterations = Compottie.IterateForever,\n        clipSpec = LottieClipSpec.Progress(0.5f, 0.75f),\n    )\n}\n```\n\n## dotLottie (ZIP)\n\n[dotLottie ](https://dotlottie.io/) is an open-source file format that aggregates one or more Lottie files and their associated resources into a single file. They are ZIP archives compressed with the Deflate compression method and carry the file extension of \".lottie\".\n\ndotLottie animations are up to 10x smaller in size and can have auto-linked bundled assets (as well as external assets ofc).\n\n`compottie-dot` module is required to use dotLottie animations in your app. It brings the new type of composition spec - `LottieCompositionSpec.DotLottie`.\n\nYou can also use `DotLottie` composition spec even without making a .lottie file just by ZIPping\nyour animation with assets using deflate algorithm. The only limitation - animation can't be named\nas \"manifest.json\" and should contain exactly one .json file.\n\nThe `DotLottie` composition spec works both with dotLottie and simple ZIP files.\nFor dotLottie files you can specify the animation to run if archive contains multiple animations\n\n```kotlin\nfun LottieCompositionSpec.Companion.DotLottie(\n    archive: ByteArray,\n    animationId: String?\n) : LottieCompositionSpec\n```\n\n## Images\n\nImages should be avoided whenever possible. They are much larger, less performant, and can lead to pixelation. Whenever possible, try and make your animation consist solely of vectors. However, Lottie does support images in one of 4 ways:\n1. Baked into the Lottie json file. This is done via an option in the exporter (such as teh Bodymovin After Effects plugin). When done, images are encoded as a base64 string and embedded directly in the json file. This is the simplest way to use images because everything is contained in a single file and no additional work is necessary to make them work;\n2. Zipped with the json file in a single zip file. When parsing the animation, Lottie will unzip the animation and automatically link any images in zip file to the composition. These zip files can be stored in assets and loaded via `LottieCompositionSpec.DotLottie` (requires `compottie-dot` module) or downloaded via the internet and loaded via `LottieCompositionSpec.Url`;\n3. External images provided by `LottieAssetsManager`;\n4. Via dynamic properties.\n\n`LottieAssetsManager` should be passed to `rememberLottieComposition` to load external resources.\n`compottie-resources` provides ready-to-use implementation that loads assets from compose-resources:\n\n```kotlin\nval painter = rememberLottiePainter(\n    composition = composition,\n    assetsManager = rememberResourcesAssetsManager(\n        directory = \"files\", // by default\n        readBytes = Res::readBytes\n    )\n)\n```\n\n## Fonts\n\nText can be drawn in 2 ways: using fonts and using glyphs (when characters are baked to the animation as lottie shapes)\n\n`LottieFontManager` should be passed to `rememberLottiePainter` to use custom fonts.\n`compottie-resources` provides ready-to-use implementation that loads fonts from compose-resources:\n\n```kotlin\nval painter = rememberLottiePainter(\n    composition = composition,\n    fontManager = rememberResourcesFontManager { fontSpec -\u003e\n        when (fontSpec.family) {\n            \"Comic Neue\" -\u003e Res.font.ComicNeue\n            else -\u003e null // default font will be used\n        }\n    }\n)\n```\n\n## URL loading\nTo load images remotely `compottie-network` module should be added as a dependensy.\nThis module brings an additional composition spec called `LottieCompositionSpec.Url`\n```kotlin\nfun LottieCompositionSpec.Companion.Url(\n    url : String,\n    format: LottieAnimationFormat,\n    client: HttpClient,\n    request : NetworkRequest,\n    cacheStrategy: LottieCacheStrategy,\n)\n```\nthat can be used to load JSON and dotLottie animations from the Internet.\n\n`LottieAnimationFormat` is used to determine wheither animation is a JSON or dotLottie. If you left it `Undefined`,\ncomposition spec will automatically detect is this a JSON or dotLottie file.\n\nKtor HTTP client can be provided with `client` parameter.\n\nCaching strategy can be set with `cacheStrategy` parameter. By default animations are cached in the\ndevice temp directory.\n\nThe network module also brings the `NetworkAssetsManager` that have similar parameters and can be used to load image assets.\nIf you are using Url composition spec then specifying `NetworkAssetsManager` is redundant.\nUrl composition spec automatically prepares url assets\n\n## Dynamic Properties\n\nLottie allows you to update animation properties at runtime. Some reasons you may want to do this are:\n1. Change colors for day/night or other app theme.\n2. Localize animation text\n3. Change the progress of a specific layer to show download progress.\n4. Change the size and position of something in response to a gesture.\n\nDynamic properties are created with `rememberLottieDynamicProperties`\n\n```kotlin\nval painter = rememberLottiePainter(\n    composition = composition,\n    dynamicProperties = rememberLottieDynamicProperties {\n        shapeLayer(\"Precomposition 1\", \"Shape Layer 4\") {\n            transform {\n                rotation { current -\u003e current * progress }\n            }\n            fill(\"Group 1\", \"Fill 4\") {\n                color { Color.Red }\n                alpha { .5f }\n            }\n            group(\"Group 4\") {\n                ellipse(\"Ellipse 1\") {\n                    // configure size, position of the ellipse named \"Ellipse 1\"\n                }\n                stroke(\"Ellipse 1 Stroke\") {\n                    // configure stroke named \"Ellipse 1 Stroke\" in the same group\n                }\n            }\n        }\n    }\n) \n```\n\nYou can also use wildcards for declaring dynamic properties, where `**` is any level deep wildcard\nand `*` is one level deep.\n\n```kotlin\nval painter = rememberLottiePainter(\n    composition = composition,\n    dynamicProperties = rememberLottieDynamicProperties {\n        \n        // for each layer named 'Shape Layer 4' on any level deep\n        shapeLayer(\"**\", \"Shape Layer 4\") {\n            // for each fill named 'Fill 4' on the 2nd level deep\n            fill(\"*\", \"Fill 4\") {\n                color { Color.Red }\n                alpha { .5f }\n            }\n        }\n    }\n) \n```\n\nNote, that final property building blocks (such as rotations, color, alpha) are called on EACH ANIMATION FRAME and should be cached if they don't rely on progress and have allocations or hard computations.\n\nMore info about dynamic properties for those who is not familiar with AE / Lottie format can be found [here](/dynamic_properties.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexzhirkevich%2Fcompottie","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexzhirkevich%2Fcompottie","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexzhirkevich%2Fcompottie/lists"}