From android-skills
Guides image loading in Compose Compose Multiplatform with Coil 3, covering AsyncImage variants, KMP setup with LocalPlatformContext, and performance guardrails for lists.
How this skill is triggered — by the user, by Claude, or both
Slash command
/android-skills:coil-composeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This reference covers the KMP specifics and two performance guardrails, not the basics of `AsyncImage` / `SubcomposeAsyncImage` / `ImageRequest` / `placeholder` / `error` / `contentDescription` / a shared `ImageLoader`.
This reference covers the KMP specifics and two performance guardrails, not the basics of AsyncImage / SubcomposeAsyncImage / ImageRequest / placeholder / error / contentDescription / a shared ImageLoader.
LocalPlatformContext, not LocalContextCoil 3 is fully multiplatform — AsyncImage / SubcomposeAsyncImage / rememberAsyncImagePainter are identical in commonMain, with no expect/actual needed. The one swap: use LocalPlatformContext.current, not LocalContext.current (Android-only; a compile error in commonMain). It resolves to android.content.Context on Android and PlatformContext.INSTANCE on other targets.
// commonMain — works on all platforms
AsyncImage(
model = ImageRequest.Builder(LocalPlatformContext.current).data(url).crossfade(true).build(),
contentDescription = "User avatar",
modifier = Modifier.size(48.dp).clip(CircleShape),
)
Singleton setup (KMP): call SingletonImageLoader.setSafe { ImageLoader.Builder(it).crossfade(true).build() } once early in the app lifecycle, or pass an imageLoader explicitly. coil-compose vs coil-compose-core: with coil-compose, AsyncImage without an imageLoader argument uses the singleton automatically; with coil-compose-core, the imageLoader parameter is required (no singleton convenience). Add a platform network engine as needed (e.g. coil-network-ktor3 for KMP).
SubcomposeAsyncImage is significantly slower than regular composition — never use it inside LazyColumn / LazyRow. It creates a subcomposition per item; during scroll that overhead accumulates into visible jank. For custom loading/error states in a list, use AsyncImage with placeholder / error parameters instead — same visual result, no subcomposition.
rememberAsyncImagePainter does NOT infer the display size from layout constraints — without an explicit .size() it loads the image at its original dimensions (a 4000×3000 photo shown at 64dp still occupies the full bitmap in memory → OOM in a 50-item list). Reach for it only when a Painter is strictly required (Canvas, Icon, a custom draw); always pass .size(). Otherwise use AsyncImage, which sizes automatically.
// only when a Painter is genuinely required — explicit size is mandatory
val painter = rememberAsyncImagePainter(
ImageRequest.Builder(LocalPlatformContext.current).data(url).size(Size(128, 128)).build(),
)
Image(painter = painter, contentDescription = null)
npx claudepluginhub rcosteira79/android-skills --plugin android-skillsProvides image loading patterns for Android Compose using Coil: AsyncImage, SubcomposeAsyncImage, caching strategies, transformations, placeholders, error handling. Useful for mobile apps.
Provides patterns for shared UI in Compose Multiplatform across Android, iOS, Desktop, and Web: state management with ViewModels/StateFlow, navigation, theming, and performance.
Provides Compose Multiplatform and Jetpack Compose patterns for KMP projects — state management, navigation, theming, performance, and platform-specific UI.