Using Ktor in Kotlin Multi Platform Projects
Read free for non-members.
Using Ktor in Kotlin Multi Platform Projects
Read free for non-members.
The mobile development world is rapidly shifting its weight toward Kotlin Multiplatform (KMP). The idea of writing your business logic once and sharing it across Android and iOS is brilliant. But what about the network layer?
In this guide, we will unpack every major feature of the Ktor Client in a KMP setup: from initialization and serialization to engines, logging, auth interception.

Photo by Taylor Vick on Unsplash
Here we go:
1. Setup
Ktor uses an engine-based architecture. You write a single client interface in your shared code, but under the hood, Ktor uses platform-specific engines: OkHttp or Android for Android, and Darwin (NSURLSession) for iOS.
Add the following dependencies to your shared/build.gradle.kts file:

https://gist.github.com/faruktoptas/71bacb2e406c73171e3b746f66372d56#file-gradle-kts
Choosing the Appropriate Engine
One of the most powerful architectural differences between Retrofit and Ktor is how they handle the actual network execution. Ktor, on the other hand, abstracts the low-level network operations into Engines
When setting up your Ktor client, you have to choose which engines to target in your platform-specific source sets:
- Android (
OkHttp, Android or CIOEngine): While Ktor offers a pureAndroidengine, the**OkHttpengine** is highly recommended for developers migrating from Retrofit. It allows you to reuse your existing OkHttp configurations, such as custom interceptors, certificate pinners, or authenticator configurations, making your migration gradual and low-risk. - iOS (
Darwin or CIOEngine): TheDarwinengine is the gold standard for iOS in KMP. It uses iOS's nativeNSURLSessionunder the hood. This ensures that your shared networking code automatically respects iOS-specific behaviors, such as native background upload/download capabilities and system-level proxy configurations. - Other Platforms: If you expand your KMP project in the future, Ktor has you covered. You can use the
CIO(Coroutine-based I/O) engine for a pure Kotlin implementation on Desktop/Backend, or theJsengine if you decide to target the Web.
Create Ktor Client Instance
In Ktor, features are modularized into Plugins. You only install what you actually need. Here is a production-ready configuration that features almost every plugin available:

https://gist.github.com/faruktoptas/71bacb2e406c73171e3b746f66372d56#file-ktor1-kt
One of the biggest friction points when moving away from Retrofit is dealing with inconsistent API responses (like getting a null when you expect a default value, or a backend adding new fields that crash your app).
By default, Kotlinx.Serialization optimizes your outgoing POST/PUT request payloads. If a property in your data class has a default value, Ktor won’t send it over the wire if it matches the default.
By utilizing these configuration flags below, your networking layer becomes significantly more resilient to unexpected backend updates than a standard setup.

https://gist.github.com/faruktoptas/71bacb2e406c73171e3b746f66372d56#file-ktor2-kt
Standard CRUD Operations (GET, POST, PUT, DELETE)
Ktor is built natively on top of Kotlin Coroutines, meaning all network operations are inherently suspend functions.
Let’s define our data models:

https://gist.github.com/faruktoptas/71bacb2e406c73171e3b746f66372d56#file-ktor3-kt
Sending requests:

https://gist.github.com/faruktoptas/71bacb2e406c73171e3b746f66372d56#file-ktor3-kt
Exception Handling
Handling unexpected HTTP statuses or network drops cleanly is crucial for UX. Ktor provides ResponseException and its subclasses to catch errors based on status codes.

https://gist.github.com/faruktoptas/71bacb2e406c73171e3b746f66372d56#file-ktor4-kt
Pipeline Interception
Ktor doesn’t use standard interceptors. Instead, it views the lifecycle of a network request as a Pipeline broken down into specific Phases (such as Setup, Transform, State, and Send).
You can hook directly into these phases using a lightweight lambda function right inside your HttpClient configuration. This entirely eliminates the need to create separate boilerplate classes for basic interception tasks:

https://gist.github.com/faruktoptas/71bacb2e406c73171e3b746f66372d56#file-ktor5-kt
Request Retries
Instable network connections are a mobile developer’s nightmare. Ktor includes a dedicated, highly customizable retry plugin. You can easily configure an exponential backoff strategy to retry failed requests.

https://gist.github.com/faruktoptas/71bacb2e406c73171e3b746f66372d56#file-ktor6-kt
Native Upload and Download Progress Tracking
Showing a linear progress bar while uploading a massive profile video or downloading a large PDF is incredibly easy.

https://gist.github.com/faruktoptas/71bacb2e406c73171e3b746f66372d56#file-ktor6-kt
Local Response Caching
Ktor provides a platform-agnostic HttpCache plugin. It strictly honors standard HTTP cache headers (Cache-Control, ETag, Last-Modified) and manages caching flawlessly across both Android and iOS without requiring extra native configurations.

Compile-Time Type-Safe Routing
Ktor takes code safety a massive step forward with its Resources library. Instead of hardcoding URLs as error-prone strings throughout your repositories, you can model your API paths as type-safe, compile-time checked Kotlin classes:

https://gist.github.com/faruktoptas/71bacb2e406c73171e3b746f66372d56#file-ktor6-kt
Unit Testing (Mock Engine)
Ktor includes a native, completely in-memory MockEngine. This lets you simulate actual server responses locally, making your shared architecture (commonMain) unit tests blindingly fast and entirely independent of an internet connection:

https://gist.github.com/faruktoptas/71bacb2e406c73171e3b746f66372d56#file-ktor6-kt
Using Ktor Client in your Kotlin Multiplatform projects eliminates the need for platform-specific networking wrappers.
- It’s Lightweight: You only include (
install) what your app actually requires. - It’s Native: It doesn’t bypass the OS; instead, it leverages the most optimized engines (
OkHttpandDarwin) natively. - It’s Future-Proof: It is maintained by JetBrains and is the official standard for the Kotlin ecosystem.
To keep your codebase clean, encapsulate your Ktor instance within a Repository pattern behind an interface. This keeps your UI layer decoupled from the networking logic, resulting in an impeccable Clean Architecture setup.
More posts about Android Development:
메타데이터
- post_id
- e2c538c9eadc
- slug
- the-mobile-development-world-is-rapidly-shifting-its-weight-toward-kotlin-multiplatform-kmp-e2c538c9eadc
- url
- https://medium.com/@faruktoptas/the-mobile-development-world-is-rapidly-shifting-its-weight-toward-kotlin-multiplatform-kmp-e2c538c9eadc
- canonical_url
- https://medium.com/@faruktoptas/the-mobile-development-world-is-rapidly-shifting-its-weight-toward-kotlin-multiplatform-kmp-e2c538c9eadc
- author_url
- https://medium.com/@faruktoptas
- status
- ok
- fetched_at
- 2026-06-18 07:02:39