A comprehensive Kotlin multiplatform toolkit for building server applications with Ktor.
🏠 Homepage (under construction)
implementation("io.github.smyrgeorge:ktkit:x.y.z")KtKit is a Kotlin multiplatform toolkit designed to speed up server-side application development with Ktor. It brings together several libraries into a cohesive set of tools that handle the repetitive aspects of backend development.
Note
Early Stage Project: KtKit is actively evolving. APIs may change between versions as we refine the abstractions based on real-world usage. Production use is possible but expect some breaking changes. Feedback and contributions are highly appreciated!
What it does (today):
- Provides a small application bootstrap around Ktor with DI, JSON, and auto-registered REST handlers
- Standardizes request handling with tracing, auth/permissions hooks, and RFC 9457-style API errors
- Exposes basic health and metrics endpoints for services built on the toolkit
- Offers TOML configuration loading with environment-variable interpolation and file/resource merging
- Adds convenience helpers for retries, JSON/TOML utilities, and KMP-friendly file/http/process access
- Uses Arrow (Raise/Either) and Kotlin context parameters to keep error handling and context passing lightweight
Planned features:
Applicationwrapper for Ktor server startup/shutdown, JSON setup, Koin DI, and routingAbstractRestHandlerwith typed request helpers,ExecContextpropagation, and error mapping- Built-in
/api/status/healthand/api/status/metricsendpoints - Error model (
ErrorSpec/ApiError) aligned with RFC 9457 conventions - Config loader for TOML with environment substitution and layered overrides
Warning
The XRealNamePrincipalExtractor and XRealNameRestClient use a base64-encoded JSON header (x-real-name) to
identify the authenticated user. This mechanism is not safe to expose directly to the internet.
This pattern assumes a trusted reverse proxy or API gateway sits in front of your application and:
- Authenticates the user (e.g., via OAuth, JWT, or session cookies)
- Strips any incoming
x-real-nameheader from client requests - Sets the
x-real-nameheader with the authenticated user's information before forwarding
If your application is exposed directly to the internet without such a proxy, any client can forge the header and impersonate any user. Only use this extractor when your application runs behind a trusted infrastructure layer that controls this header.
A multiplatform REST client abstraction built on Ktor's HttpClient with functional error handling via Arrow's Raise.
HttpClientFactoryfor creating pre-configured HttpClient instances with timeouts, connection pooling, and JSON setupAbstractRestClientbase class with typed HTTP methods (GET, POST, PUT, PATCH, DELETE, etc.)- Built-in implementations:
BearerRestClient(Bearer token auth) andXRealNameRestClient(X-Real-Name header auth) - Error handling via sealed
RestClientErrorSpechierarchy
A coroutine-first SQL toolkit with compile-time query validations for Kotlin Multiplatform. PostgreSQL, MySQL/MariaDB, and SQLite supported.
DatabaseServicehelpers for error mapping and traced transactionsAuditableRepositoryhooks forcreatedAt/createdBy/updatedAt/updatedByAuditableDatabaseServiceinterface for services with auditable entities and asave()extensionJsonSupportutility for JSON column serialization with sqlx4k'sValueEncodersystem
A lightweight message queue. Like AWS SQS and RSMQ but on Postgres.
Pgmqwrapper andAbstractPgmqEventHandlerwith trace/user propagation- Consumer lifecycle helpers with retry + shutdown handling
The example module shows how Arrow's Raise and Kotlin context parameters keep service code compact while
preserving explicitness around errors and execution context:
class TestService(
override val db: Driver,
override val repo: TestRepository,
) : AuditableDatabaseService<Test> {
val log = Logger.of(this::class)
context(_: ExecContext, _: QueryExecutor)
private suspend fun findAll(): List<Test> = db { repo.findAll() }
context(_: ExecContext, _: Transaction)
suspend fun test(): List<Test> {
log.info { "Fetching all tests" }
return findAll().also {
log.info { "Fetched ${it.size} tests" }
}
}
}The execution context is a coroutine context element that also implements Arrow's Raise and log4k's tracing context:
class ExecContext(
val reqId: String,
val reqTs: Instant,
val principal: Principal,
// Only a part of the context is presented here.
// Check the documentation for more information.
) : Raise<ErrorSpec>, TracingContext by tracing, CoroutineContext.ElementThis lets handlers and services raise domain errors, access tracing, and carry request metadata without threading
parameters manually. The context is propagated in two ways at once: via CoroutineContext and via context
parameters in function signatures.
Check the example application here.
# Build all modules, for Jvm and your current platform
./gradlew build
# Build all modules for all supported platforms
./gradlew build -Ptargets=all
#The project includes a docker-compose.yml for PostgreSQL:
This is an open-source project. Contributions are welcome!
Check the repository for license information.
Yorgos S. (@smyrgeorge)