# Coil: an image loader for Android and Compose Multiplatform

> Coil is a Kotlin-first image loading library that depends only on Kotlin, Coroutines and Okio. It is easy to add to a Compose screen, but the network layer is a separate artifact you have to choose.

**coil-kt/coil** — Image loading for Android and Compose Multiplatform.

- Repository: https://github.com/coil-kt/coil
- Website: https://coil-kt.github.io/coil/
- Stars: 11,909 · Forks: 792
- Language: Kotlin
- License: Apache-2.0
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/coil-kt-coil

## What Coil is for, and who should reach for it

Coil is an image loading library for Android and Compose Multiplatform, written in Kotlin. The name is an acronym for Coroutine Image Loader, which tells you the execution model: requests are coroutine-based, so a load can be paused or cancelled when the composable that asked for it leaves the screen. The README lists four properties it claims for itself: fast, lightweight, easy to use, modern. Of those, the dependency claim is the one you can check from the repository layout. Coil states it depends only on Kotlin, Coroutines and Okio, and that it works with Google's R8 code shrinker.

The intended user is an app developer writing Kotlin UI, mostly in Compose. The repository ships separate modules for the pieces that not every app needs: coil-gif, coil-svg, coil-video, coil-network-okhttp, coil-network-ktor2 and coil-network-ktor3. That split is the design statement. You do not get GIF decoding, SVG rendering or video frame extraction unless you add the module, and you do not get a network client until you pick one. If you are loading images from local resources or a ByteArray only, the core artifacts are enough.

It is a poor fit for a Java-only codebase, for a UI built on the classic Android View system without Kotlin, or for a project that has already standardised on a different image pipeline and does not want a second cache. The README does not describe a non-Compose API path in the quick start; the example given is the AsyncImage composable.

## How Coil splits loading into core, network and Compose layers

The module list in the repository root is the clearest description of the architecture. coil-core holds the loader itself. coil-compose and coil-compose-core sit above it and provide the composable API. coil-network-core defines the network abstraction, and the three network modules (okhttp, ktor2, ktor3) are concrete implementations of it. Optional decoders live in their own modules: coil-gif, coil-svg, coil-video. There is also coil-network-cache-control, coil-lint, coil-test and a coil-bom for version alignment.

That means a request travels through at least three layers you can swap independently. The Compose layer hands a model to the loader, the loader consults its memory and disk caches, and if the image is not cached it goes out through whichever network artifact you installed. Because the network piece is an interface with multiple implementations, choosing OkHttp versus Ktor is a real decision rather than a formality: if your app already uses OkHttp for its API calls, sharing that stack avoids a second HTTP client; if it uses Ktor, the ktor2 or ktor3 module matches the Ktor major version you already depend on. The README does not document how the caches are keyed or sized, so treat cache tuning as something to read about in the full documentation rather than in the quick start.

The release history shows a steady patch cadence: 3.6.1 on 2026-09-01, 3.6.2 on 2026-09-04, 3.6.3 on 2026-09-18. The last push to the repository was on 2026-09-21. That is a project that ships fixes often, which cuts both ways: you get corrections quickly, and you also need a version policy so that patch releases do not arrive unannounced in your build.

## Installing Coil and loading your first image with AsyncImage

The README's quick start has two steps. First, add the Compose artifact and a networking artifact. Both use the io.coil-kt.coil3 group, and both are pinned to the same version in the example. Note that the group is coil3, not the older io.coil-kt used by Coil 2.x; the related searches show people still typing both, so check which one your project already resolves before you add a line.

```kotlin
implementation("io.coil-kt.coil3:coil-compose:3.6.3")
implementation("io.coil-kt.coil3:coil-network-okhttp:3.6.3")
```

Second, load an image. The README's example passes a URL string as the model and a null content description, which is the minimum viable call. In a real screen you would pass a description for accessibility.

```kotlin
AsyncImage(
    model = "https://example.com/image.jpg",
    contentDescription = null,
)
```

After adding both dependencies and the composable, the expected result is that the image at that URL renders inside the composable's bounds. If nothing appears, the first thing to check is whether a network artifact is actually on the classpath: coil-compose alone does not include one, and the README presents the networking library as a separate import rather than an optional extra. The README points to the full documentation at coil-kt.github.io/coil/getting_started/ for anything beyond this, and the repository also contains sample projects under samples/compose, samples/compose-android, samples/shared and samples/view if you want a working reference. The README does not give a Gradle version catalog snippet, so if you use libs.versions.toml you will be translating these coordinates yourself.

## The network artifact is the failure point, not the composable

The most common way a Coil setup goes wrong is also the least visible: the app compiles, AsyncImage renders, and no image ever arrives because no network implementation was added. The README's quick start makes this explicit by importing coil-network-okhttp alongside coil-compose, but a developer who copies only the first line gets a runtime problem rather than a build error. That is a genuine sharp edge in the packaging, and it is not a bug so much as a consequence of keeping the core free of an HTTP client.

The second limitation is the Compose assumption. Coil's quick start is written entirely around AsyncImage. If your screen is a RecyclerView or a classic View hierarchy, the README does not show you the path, and the repository's samples directory has a samples/view entry whose contents are not described in the README. You would be reading the full documentation to find the non-Compose API.

The third is scope creep through optional modules. GIF, SVG and video support are separate artifacts (coil-gif, coil-svg, coil-video). Each one is a dependency you add and a decoder you carry. An app that loads only JPEGs and PNGs should not include them, and an app that adds all three without checking what formats its backend actually serves is paying for code it never runs. The README does not state the size cost of any module, so that trade-off has to be measured in your own build rather than assumed.

## Coil compared with Glide and Picasso

The obvious alternatives are Glide and Picasso, the two long-standing Android image loaders. The difference in approach is not feature parity, it is the execution and API model. Coil is built on Kotlin coroutines and Okio, and its primary API is a Compose composable, AsyncImage. Glide and Picasso grew up around the View system and Java, with their own request builders and target callbacks. If your UI is Compose and your code is Kotlin, Coil's API is the one that reads like the rest of your codebase, which is what the README means when it calls the library Kotlin-first.

A second difference is the dependency surface. Coil states that it depends only on Kotlin, Coroutines and Okio, and that it interoperates with OkHttp and Ktor rather than requiring one. That is a narrower base than a loader that bundles its own HTTP stack, and it is why the network artifact is a separate decision here. The cost of that choice is the failure mode described above: fewer transitive dependencies, but one more coordinate to remember.

Where Glide or Picasso may still be the better answer: an existing large View-based codebase, a Java module, or a project that already depends on Glide's transformation and lifecycle behaviour and has no reason to migrate. The README does not claim Coil is a drop-in replacement for either, and there is no migration guide in the repository documentation.

## Maintenance, versioning and the Apache-2.0 licence

The repository is not archived, and the last push was on 2026-09-21. Recent releases are 3.6.1 (2026-09-01), 3.6.2 (2026-09-04) and 3.6.3 (2026-09-18), so the project is being released on a short cycle. For an adopter, that means upgrade cost is mostly the cost of keeping up with patches rather than absorbing rare large jumps. The repository keeps a CHANGELOG.md at the root, which is where you would read what changed between the version you have and the one you are moving to. The README does not document a deprecation policy or a support window for older minor versions, so a team that pins a version and stays there for a year should check the changelog themselves before assuming an upgrade is mechanical.

There is a coil-bom module, which is the standard way to align versions across several Coil artifacts. If you use coil-compose, coil-network-okhttp and coil-gif together, the BOM is the mechanism that keeps them on one version, and the README does not mention it, so you would find it from the repository layout or the full documentation instead.

Licensing is Apache-2.0. The README reproduces the licence header, which requires that the licence and copyright notice be included in distributions and states that the software is provided without warranties or conditions. That is a permissive licence, and it is the same one used by many Android libraries, so it is unlikely to conflict with a typical app. This is a description of what the file says, not legal advice; if your organisation has a licence review process, run the Apache-2.0 text through it.

## Conclusion

Adopt Coil if you are building an Android or Compose Multiplatform UI in Kotlin and want image loading through a Compose composable rather than a view-based API. Do not adopt it if your stack is Java, XML views without Kotlin, or a UI framework that is not Compose. Before you commit, verify three things: which network artifact you need (coil-network-okhttp, coil-network-ktor2 or coil-network-ktor3), whether your R8 configuration is in place, and which release your project already resolves. The README's own quick start pins 3.6.3, and the repository's release history shows 3.6.1 and 3.6.2 shipped in the weeks before it, so decide whether you track patch releases or pin.

## FAQ

### What is Coil in Compose?

Coil is an image loading library for Android and Compose Multiplatform, and the name stands for Coroutine Image Loader. In Compose you use it through the AsyncImage composable, which takes a model such as a URL and a content description. The quick start requires both coil-compose and a networking artifact such as coil-network-okhttp.

### Which Coil artifact should I add for Compose?

The README's quick start adds io.coil-kt.coil3:coil-compose together with a networking library, and shows io.coil-kt.coil3:coil-network-okhttp as the example. The network piece is separate because coil-compose does not include an HTTP client. If your app uses Ktor instead, the repository also contains coil-network-ktor2 and coil-network-ktor3 modules.

### Does Coil support GIF, SVG and video?

The repository has separate coil-gif, coil-svg and coil-video modules, so support for those formats is opt-in rather than included in the core artifacts. The README does not describe how each decoder is configured, so you would need the full documentation for that. Adding a module you do not need means carrying a decoder your app never invokes.

### What licence does Coil use?

Coil is licensed under Apache-2.0, and the README reproduces the standard licence header. That header requires the licence and copyright notice to be included in distributions and states that the software comes without warranties or conditions. It is a permissive licence, but this is a reading of the file rather than legal advice.

## Sources

- [coil-kt/coil on GitHub](https://github.com/coil-kt/coil)
- [License: Apache-2.0](https://github.com/coil-kt/coil/blob/main/LICENSE)
- [Project website](https://coil-kt.github.io/coil/)
- [README](https://github.com/coil-kt/coil/blob/main/README.md)
- [Releases](https://github.com/coil-kt/coil/releases)

---

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