{"id":48833580,"url":"https://github.com/valentinilk/compose-shimmer","last_synced_at":"2026-04-14T22:02:25.174Z","repository":{"id":41488304,"uuid":"399151906","full_name":"valentinilk/compose-shimmer","owner":"valentinilk","description":"A simple shimmer library for Jetpack Compose.","archived":false,"fork":false,"pushed_at":"2026-04-14T07:08:18.000Z","size":5300,"stargazers_count":1004,"open_issues_count":10,"forks_count":47,"subscribers_count":13,"default_branch":"master","last_synced_at":"2026-04-14T09:13:04.246Z","etag":null,"topics":["android","jetpack-compose"],"latest_commit_sha":null,"homepage":"https://valentinilk.github.io/compose-shimmer/","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/valentinilk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-08-23T15:18:05.000Z","updated_at":"2026-04-14T07:08:25.000Z","dependencies_parsed_at":"2025-01-29T19:28:25.438Z","dependency_job_id":"ebb5e6ce-b33c-4931-ba46-4745b60757e0","html_url":"https://github.com/valentinilk/compose-shimmer","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/valentinilk/compose-shimmer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valentinilk%2Fcompose-shimmer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valentinilk%2Fcompose-shimmer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valentinilk%2Fcompose-shimmer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valentinilk%2Fcompose-shimmer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/valentinilk","download_url":"https://codeload.github.com/valentinilk/compose-shimmer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/valentinilk%2Fcompose-shimmer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31817128,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T18:05:02.291Z","status":"ssl_error","status_checked_at":"2026-04-14T18:05:01.765Z","response_time":153,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["android","jetpack-compose"],"created_at":"2026-04-14T22:02:23.140Z","updated_at":"2026-04-14T22:02:25.138Z","avatar_url":"https://github.com/valentinilk.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shimmer for Jetpack Compose \u0026 Compose Multiplatform\n\nA library which offers a shimmering effect for Compose.\n\n\u003cimg src=\"https://user-images.githubusercontent.com/1201850/131474443-620d0777-5b42-4914-839d-e6250b083538.gif\" width=\"500\"  alt=\"\"\u003e\n\n## Setup\n\nThe library is available on `mavenCentral()`.\n\n```kotlin\ndependencies {\n    implementation(\"com.valentinilk.shimmer:compose-shimmer:1.4.0\")\n}\n```\n\n#### Multiplatform Targets\n\nSupported CMP targets are: `Android`, `iOS`, `JVM (Desktop)`, `JS (Browser)` and `Wasm (WebAssembly)`.\n\n#### Compose Multiplatform Version\n\nIn case of compatibility issues, select a library version that is based on the same compose version as your project.\n\n| Shimmer Version | Based on Compose |\n|-----------------|------------------|\n| 1.5.0-beta02    | 1.11.0-beta02    |\n| 1.4.0           | 1.10.3           |\n| 1.3.3           | 1.8.1            |\n| 1.3.2           | 1.7.3            |\n\n## Quick Start\n\nSimply apply the `shimmer` modifier to any UI of your choice. The code below will emit the shimmering UI that can be\nseen in the GIF above.\n\n```kotlin hl_lines=\"5\"\n@Composable\nfun ShimmeringPlaceholder() {\n    Row(\n        modifier = Modifier\n            .shimmer() // \u003c- Affects all subsequent UI elements\n            .fillMaxWidth()\n            .padding(16.dp),\n        horizontalArrangement = Arrangement.spacedBy(16.dp),\n    ) {\n        Box(\n            modifier = Modifier\n                .size(80.dp, 80.dp)\n                .background(Color.LightGray),\n        )\n        Column(\n            verticalArrangement = Arrangement.spacedBy(16.dp),\n        ) {\n            Box(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .height(24.dp)\n                    .background(Color.LightGray),\n            )\n            Box(\n                modifier = Modifier\n                    .size(120.dp, 20.dp)\n                    .background(Color.LightGray),\n            )\n        }\n    }\n}\n```\n\n## Modifier placement\n\nAs usual with [modifiers](https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier) the order\nmatters.\nEvery UI component defined **after** the `shimmer` modifier will be affected by the animation. This includes child views\nand other modifiers:\n\nThe first example demonstrates that only the inner `Box` is shimmering, even though the `shimmer` has been added to\nthe outer `Box`'s modifier stack. The blue `background` is not shimmering, as it's sitting above the `shimmer` modifier.\n\n```kotlin hl_lines=\"5\"\nBox(\n    modifier = Modifier\n        .size(128.dp)\n        .background(Color.Blue)\n        .shimmer(),\n    contentAlignment = Alignment.Center\n) {\n    Box(\n        modifier = Modifier\n            .size(64.dp)\n            .background(Color.Red)\n    )\n}\n```\n\n\u003cimg src=\"https://user-images.githubusercontent.com/1201850/131474508-c572076c-d707-4ba1-9e84-729c1dc06f3f.gif\" width=\"128\" height=\"128\" alt=\"\"\u003e\n\n\nIf the modifier, however, is applied earlier, the outer `Box`'s `background` modifier is affected by the\n`shimmer` as well.\n\n```kotlin hl_lines=\"4\"\nBox(\n    modifier = Modifier\n        .size(128.dp)\n        .shimmer()\n        .background(Color.Blue),\n    contentAlignment = Alignment.Center\n) {\n    Box(\n        modifier = Modifier\n            .size(64.dp)\n            .background(Color.Red)\n    )\n}\n```\n\n\u003cimg src=\"https://user-images.githubusercontent.com/1201850/131474532-ce7d37c5-9af6-4577-82c2-737591f8c0c2.gif\" width=\"128\" height=\"128\" alt=\"\"\u003e\n\n## Theming\n\nThe library includes a `ShimmerTheme` which can be provided as\na [local composition](https://developer.android.com/reference/kotlin/androidx/compose/runtime/CompositionLocal).\nA good practice would be to integrate the theming into\nyour [customized MaterialTheme](https://developer.android.com/jetpack/compose/designsystems/custom).\nThere is no need to wrap every single `shimmer` into a `CompositionLocalProvider`.\n\n```kotlin\nval yourShimmerTheme = defaultShimmerTheme.copy(/* Set your desirable values */)\n\nCompositionLocalProvider(\n    LocalShimmerTheme provides yourShimmerTheme\n) {\n    /* content */\n}\n```\n\nThe theme can also be passed as a parameter by using the `rememberShimmer(...)` function, which is\nexplained further down below.\n\nThe theme itself offers a few simple configurations like the shimmer's `rotation` or `width`.\nAdditionally, a few unabstracted objects like an `AnimationSpec` or `BlendMode` are exposed. While\nthis violates the principles\nof [information hiding](https://en.wikipedia.org/wiki/Information_hiding), it allows for some great\ncustomizations.\n\nFor further information have a look at documentation in data class itself and have a look at\nthe `ThemingSamples` in the sample app.\n\n\u003cimg src=\"https://user-images.githubusercontent.com/1201850/131474645-a854a5ed-c390-4695-b4e4-e73224f2240c.gif\" width=\"250\"  alt=\"\"\u003e\n\n## Advanced Usage\n\nThe default `shimmer()` modifier creates a shimmering animation, which will traverse over the view\nin a certain time. That means that the animation will have a different velocity, depending on the\nsize of the view.\n\nIf you apply the modifier to multiple views, each of a different size, then each shimmer will have\nits own velocity. This effect can be seen in the following GIF:\n\n\u003cimg src=\"https://user-images.githubusercontent.com/1201850/131474721-29a57e04-139c-44b6-8721-5fb674706dc8.gif\" width=\"250\"  alt=\"\"\u003e\n\nThat might not always be the desired effect, that's why the library offers a way to set the\nboundaries for the animation:\n\n```kotlin\nval shimmerInstance = rememberShimmer(shimmerBounds = ShimmerBounds.XXX)\nBox(modifier = Modifier.shimmer(shimmerInstance))\n```\n\n### ShimmerBounds.View (default)\n\nThe view's height and width will be used as the boundaries for the animation.\nThis option was used to create the GIFs shown above and should be sufficient for most use cases.\n\n### ShimmerBounds.Window\n\nThis option uses the window's height, with and coordinate system for the calculations. It will\ncreate a shimmer that travels over the whole window instead of only the views. But only views that\nhave the shimmer modifier attached will be affected.\n\nBe aware that this option might look odd on scrollable content, because the shimmer will be\npositioned relative to the window. So the shimmer will not be moved together with the content.\n\n```kotlin\nColumn {\n    val shimmerInstance = rememberShimmer(shimmerBounds = ShimmerBounds.Window)\n    Text(\"Shimmering Text\", modifier = Modifier.shimmer(shimmerInstance))\n    Text(\"Non-shimmering Text\")\n    Text(\"Shimmering Text\", modifier = Modifier.shimmer(shimmerInstance))\n}\n```\n\n\u003cimg src=\"https://user-images.githubusercontent.com/1201850/131474786-298be2fe-979a-4be4-b4ec-ef3c7d4026fa.gif\" width=\"250\"  alt=\"\"\u003e\n\n### ShimmerBounds.Custom\n\nThe downsides of the `Window` option is why the `ShimmerBounds.Custom` option exists.\nBy using this option, the shimmer and its content will not be drawn until the bounds are set\nmanually by using the `updateBounds` method on the `Shimmer`.\nThis can be used to attach the shimmer to a scrollable list for example. Or simply use the default\n`ShimmerBounds.View` option.\n\n```kotlin\nval shimmerInstance = rememberShimmer(ShimmerBounds.Custom)\nColumn(\n    modifier = Modifier\n        .fillMaxSize()\n        .verticalScroll(rememberScrollState())\n        .onGloballyPositioned { layoutCoordinates -\u003e\n            // Util function included in the library\n            val position = layoutCoordinates.unclippedBoundsInWindow()\n            shimmerInstance.updateBounds(position)\n        },\n) {\n    Text(\"Shimmering Text\", modifier = Modifier.shimmer(shimmerInstance))\n    Text(\"Non-shimmering Text\")\n    Text(\"Shimmering Text\", modifier = Modifier.shimmer(shimmerInstance))\n}\n```\n\n## Sample Apps\n\nSample apps for different platforms are included in the project.\nTo use them, clone the repository into a folder locally.\n\n### Android\n\nTo run the Android app, simply open the project in Android Studio. Select the `sample` configuration and run it.\n\n### iOS\n\nThe iOS app can be build and launched by using XCode. Open the `iosApp` folder with XCode as a project. Adapt the\nsigning in XCode to match your needs and launch the app on an emulator or iOS device.\n\n### Desktop\n\nThe desktop app can be launched by using the `sample.desktop` configuration in Android Studio. Or run\n`./gradlew :sample:run` in the terminal.\n\n### Browser\n\nTo run the sample in the browser, simply use the `sample.browser` configuration in Android Studio. Or run\n`./gradlew :sample:jsBrowserDevelopmentRun` in the terminal.\n\n### WebAssembly (Wasm)\n\nTo run the Wasm sample use the `sample.wasm` configuration in Android Studio or run\n`./gradlew :sample:wasmJsBrowserDevelopmentRun` in the terminal.\n\n## License\n\n```\nCopyright 2026 Valentin Ilk\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvalentinilk%2Fcompose-shimmer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvalentinilk%2Fcompose-shimmer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvalentinilk%2Fcompose-shimmer/lists"}