mcpField
C
coil-compose

coil-compose

github.com/rcosteira79Development172147 installsUpdated 7w ago
Repository

About coil-compose

A reference skill for using Coil 3 with Compose and Compose Multiplatform. It explains platform-context choices and image-loading performance constraints, including when to avoid subcomposition and how to size painter requests.

Key features

  1. 01跨平台使用 LocalPlatformContext
  2. 02设置共享 ImageLoader
  3. 03区分 coil-compose 与 core
  4. 04列表中避免 SubcomposeAsyncImage
  5. 05为 Painter 请求指定尺寸

Use cases

  1. 01在 commonMain 中加载图片
  2. 02配置跨平台图片加载器
  3. 03减少 LazyColumn 图片滚动卡顿
  4. 04避免 Painter 加载超大原图

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/rcosteira79/android-skills --skill coil-compose

After installing, type/coil-composein Claude Code to confirm it loaded.

Details

From the project README

Coil 3 for Compose & Compose Multiplatform

This reference covers the KMP specifics and two performance guardrails, not the basics of AsyncImage / SubcomposeAsyncImage / ImageRequest / placeholder / error / contentDescription / a shared ImageLoader.

KMP: LocalPlatformContext, not LocalContext

Coil 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).

Two performance guardrails

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)

Comments

Markdown supported