
KMP HTTP Client
A lightweight Kotlin Multiplatform HTTP client built on Ktor.
KMP HTTP Client provides a minimal, builder-style API for HTTP on Android and iOS. It offers typed configuration, pluggable interceptors (logging, auth, error handling), and a unified response model—reducing boilerplate and keeping a single, consistent API across platforms.
Table of Contents
Overview
| Item | Description |
|---|
| Purpose | Simplify HTTP in Kotlin Multiplatform (Android & iOS) with one API surface. |
|
Core API (Kotlin):
- Entry point:
HttpClient (default singleton + custom instances)
- Request: (builder)
Features
- Builder-style
HttpRequest with path, query, headers, and body
- Typed
HttpClientConfig (timeouts, logging, cache)
- Built-in interceptors: logging, auth, token refresh, error handling
- Custom interceptors via (Kotlin) / Swift protocol
Requirements
Installation
Android (Gradle)
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.santimattius.kmp:http-client:<version>")
}
- Engine: Ktor OkHttp (
ktor-client-okhttp).
- Initialize once (e.g.
Application#onCreate or AndroidX Startup).
iOS
The shared module produces the KMPHttpClient framework (baseName in shared/build.gradle.kts). You can:
- Xcode + KMP: Include the
shared module and use the Gradle-generated framework.
- Prebuilt XCFramework: Build
KMPHttpClient.xcframework and add it to the iOS app.
- Swift Package Manager (binary): Add a binary target pointing to the published XCFramework.
Example — SwiftPM binary target:
import PackageDescription
let package = Package(
name: "KMPHttpClient",
platforms: [.iOS(.v14)],
products: [.library(name: "KMPHttpClient", targets: ["KMPHttpClient"])],
targets: [
.binaryTarget(
name: "KMPHttpClient",
url: "https://github.com/your-org/kmp-http-client/releases/download/1.0.0/KMPHttpClient.xcframework.zip",
checksum: "<swiftpm-checksum>"
)
]
)
In Swift:
import KMPHttpClient
Skie is enabled in the shared module for better Swift interop:
skie {
swiftBundling { enabled = true }
}
Quick Start
- Initialize the client once at app startup.
- Reuse the default client or create custom instances with
HttpClient.create(...).
Kotlin (Android):
Main HttpClientConfig options:
Usage
POST with JSON body
import kotlinx.serialization.Serializable
@Serializable
data ( email: String, password: String)
: {
client = HttpClient.defaultClient()
request = HttpRequest
.post()
.path()
.header(, )
.body(LoginRequest(email, password))
.build()
response = client.execute(request)
response.isSuccessful
}
Custom client and interceptors
Built-in interceptors:
- AuthInterceptor — Authorization headers
- TokenRefreshInterceptor — Token refresh flow
- LoggingInterceptor — Configurable logging
- ErrorHandlingInterceptor — Map HTTP errors to exceptions
import com.santimattius.http.config.HttpClientConfig
import com.santimattius.http.config.LogLevel
import com.santimattius.http.interceptor.LoggingInterceptor
val customClient = HttpClient.create(
HttpClientConfig(baseUrl = "https://api.example.com")
.enableLogging(true)
.logLevel(LogLevel.BODY)
).addInterceptors(LoggingInterceptor())
Custom interceptor (Swift):
import KMPHttpClient
class OkHttpInterceptor: Interceptor {
func __intercept(chain: any InterceptorChain) async throws -> HttpResponse {
print("Hello from OkHttpInterceptor")
return try chain.proceed(request: chain.request)
}
}
Swift: JSON decoding
Project Structure
Best Practices
Common pitfalls:
Tech Support
This project is maintained on a best-effort basis by the core team and community. The following guidelines set expectations for support and maintenance.
Support scope
Support channels
- GitHub Issues: Bug reports and feature requests. Use the issue templates when available.
- GitHub Discussions: Questions, ideas, and community help (no guaranteed response time).
How to get help
- Search existing Issues and Discussions.
- Read this README and the referenced docs.
- Open an Issue for bugs (with minimal repro) or start a Discussion for questions.
- Be specific: environment, versions, code snippet, and what you already tried.
References