KtKit


A comprehensive Kotlin multiplatform toolkit for building server applications with Ktor.
📖 Documentation
🏠 Homepage (under construction)
Usage
implementation("io.github.smyrgeorge:ktkit:x.y.z")
Overview
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:
Modules and features
Core (ktkit)
Application wrapper for Ktor server startup/shutdown, JSON setup, Koin DI, and routing
AbstractRestHandler with typed request helpers, propagation, and error mapping
Security: X-Real-Name Header Authentication
[!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-name header from client requests
- Sets the
x-real-name header 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.
TOML Configuration Loading
ConfigPropertiesToml loads and deserializes TOML files into @Serializable data classes. It supports environment
variable interpolation (${VAR_NAME}), loading from resources or the filesystem, and merging a base config with an
override file (override values take precedence).
The load() method reads application.toml from resources as the base, then looks for an override in this order:
application.toml, config/application.toml, application.local.toml, config/application.local.toml.
@Serializable
data class AppConfig(val server: ServerConfig, val database: DatabaseConfig)
@Serializable
data ( host: String, port: )
( url: String, maxConnections: )
[server]
host = "localhost"
port = 8080
[database]
url = "postgresql://${DB_HOST}/mydb"
maxConnections = 10
[database]
maxConnections = 50
val config: AppConfig = ConfigPropertiesToml.load()
val config: AppConfig = ConfigPropertiesToml.loadFromFileSystem("path/to/config.toml")
val config: AppConfig = ConfigPropertiesToml.loadFromFileSystem(
base = "base.toml",
override = "override.toml"
)
Ktor HTTP Client (ktkit-ktor-httpclient)
A multiplatform REST client abstraction built on Ktor's HttpClient with functional error handling via Arrow's Raise.
HttpClientFactory for creating pre-configured HttpClient instances with timeouts, connection pooling, and JSON setup
AbstractRestClient base class with typed HTTP methods (GET, POST, PUT, PATCH, DELETE, etc.)
- Built-in implementations:
BearerRestClient (Bearer token auth) and XRealNameRestClient (X-Real-Name header auth)
- Error handling via sealed
RestClientErrorSpec hierarchy
sqlx4k integration (ktkit-sqlx4k)
A coroutine-first SQL toolkit with compile-time query validations for Kotlin Multiplatform. PostgreSQL,
MySQL/MariaDB, and SQLite supported.
DatabaseService helpers for error mapping and traced transactions
AuditableRepository hooks for createdAt/createdBy/updatedAt/updatedBy
AuditableDatabaseService interface for services with auditable entities and a save() extension
PGMQ integration (ktkit-sqlx4k-pgmq)
A lightweight message queue. Like AWS SQS and RSMQ but on Postgres.
Pgmq wrapper and AbstractPgmqEventHandler with trace/user propagation
- Consumer lifecycle helpers with retry + shutdown handling
Ergonomics (Arrow + context-parameters)
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 db: Driver,
repo: TestRepository,
) : AuditableDatabaseService<Test> {
log = Logger.of(::)
context(_: ExecContext, _: QueryExecutor)
: List<Test> = db { repo.findAll() }
context(_: ExecContext, _: Transaction)
: List<Test> {
log.info { }
findAll().also {
log.info { }
}
}
}
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,
) : Raise<ErrorSpec>, TracingContext by tracing, CoroutineContext.Element
This 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.
Example
Check the example application here.
Building & Development
Build
./gradlew build
Docker Setup
The project includes a docker-compose.yml for PostgreSQL:
docker-compose up -d
Contributing
This is an open-source project. Contributions are welcome!
License
Check the repository for license information.
Related Projects
- log4k – Multiplatform logging with tracing
- sqlx4k – Multiplatform database access
Author
Yorgos S. (@smyrgeorge)