
Generate compile-time dynamic proxies for interfaces, intercept synchronous and asynchronous calls, property access, and equals/hashCode/toString; supports meta-annotations and cross-module proxy discovery for zero runtime reflection.
houl# KProxyable
Compile-time Dynamic Proxies for Kotlin Multiplatform.
KProxyable is a library that brings the power of dynamic proxies to the entire Kotlin Multiplatform (KMP) ecosystem. While the JVM has java.lang.reflect.Proxy, other platforms like JS, Native, and Wasm lack a built-in mechanism to intercept interface invocations at runtime without manual boilerplate.
This library uses KSP (Kotlin Symbol Processing) to generate proxy implementations at compile-time, providing a unified, type-safe API to intercept function calls, property accesses, and standard Any methods across all targets.
suspend function calls.equals, hashCode, and toString.@HttpClient) to automatically trigger proxy generation.public or internal interfaces are supported. private interfaces cannot be proxied as the generated implementation needs to be able to see and implement the interface.KProxyable requires the KSP plugin to be applied in your project. You must use the KSP version that matches your Kotlin version.
In your root build.gradle.kts (or application module):
plugins {
// 1. Apply KSP with version matching your Kotlin version
id("com.google.devtools.ksp") version "2.0.21-1.0.28"
// 2. Apply KProxyable
id("io.github.elianfabian.kproxyable") version "1.0.5"
}The KProxyable plugin automatically:
kproxyable-runtime dependency to commonMain.kproxyable-processor for all Main and Test configurations (supporting cross-module discovery and unit tests).If you prefer to manage KSP and runtime dependencies manually:
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.elianfabian:kproxyable-runtime:1.0.5")
ksp("io.github.elianfabian:kproxyable-processor:1.0.5")
kspTest("io.github.elianfabian:kproxyable-processor:1.0.5")
}Annotate any public or internal interface with @KProxyable:
import com.elianfabian.kproxyable.KProxyable
@KProxyable
interface MyService {
fun doSomething(id: Int, name: String): String
suspend fun fetchData(query: String): List<String>
var isActive: Boolean
}The ProxyHandler is responsible for intercepting all calls to the proxy instance:
class MyHandler : ProxyHandler {
override fun onCall(function: FunctionDescriptor, args: List<Any?>): Any? {
println("Calling ${function.name} with $args")
return "Intercepted result"
}
override suspend fun onSuspendCall(function: FunctionDescriptor, args: List<Any?>): Any? {
return listOf("Async", "Result")
}
// Handle properties, equals, hashCode, and toString...
}Use the create factory method to instantiate your intercepted interface:
// In JVM projects
val service = KProxyJvm.create<MyService>(MyHandler())
// In JS projects
val service = KProxyJs.create<MyService>(MyHandler())KProxyable provides optimized entry points depending on your project type:
Use KProxyJvm for standard JVM or Android applications. It uses a lightweight ServiceLoader mechanism to discover generated registries.
Use KProxyJs for Kotlin/JS projects. It leverages global scope hooks to link generated code without reflection.
In a KMP project, you can define a shared entry point in commonMain using an expect object:
// commonMain
@KProxyRegistry
expect object MyProxyFactory : KProxyFactory
// usage
val service = MyProxyFactory.create<MyService>(MyHandler())KSP will automatically generate the actual implementation in your platform-specific source sets, aggregating all @KProxyable interfaces found in your project and its dependencies.
Instead of using @KProxyable everywhere, you can create your own domain-specific annotations:
@Target(AnnotationTarget.CLASS)
@KProxyable // This makes @MyClient a proxy trigger
annotation class MyClient
@MyClient
interface UserApi {
fun getUser(id: String): User
}KProxyable is a showcase of AI-Collaborative Engineering.
The implementation of this library, including its KSP processor and complex multi-platform CI/CD pipeline, was primarily driven by AI assistants working under human architectural guidance. This project serves as an experiment in how modern AI tools can accelerate the development of professional-grade, specialized infrastructure for the Kotlin ecosystem.
This project is licensed under the MIT License - see the LICENSE file for details.
houl# KProxyable
Compile-time Dynamic Proxies for Kotlin Multiplatform.
KProxyable is a library that brings the power of dynamic proxies to the entire Kotlin Multiplatform (KMP) ecosystem. While the JVM has java.lang.reflect.Proxy, other platforms like JS, Native, and Wasm lack a built-in mechanism to intercept interface invocations at runtime without manual boilerplate.
This library uses KSP (Kotlin Symbol Processing) to generate proxy implementations at compile-time, providing a unified, type-safe API to intercept function calls, property accesses, and standard Any methods across all targets.
suspend function calls.equals, hashCode, and toString.@HttpClient) to automatically trigger proxy generation.public or internal interfaces are supported. private interfaces cannot be proxied as the generated implementation needs to be able to see and implement the interface.KProxyable requires the KSP plugin to be applied in your project. You must use the KSP version that matches your Kotlin version.
In your root build.gradle.kts (or application module):
plugins {
// 1. Apply KSP with version matching your Kotlin version
id("com.google.devtools.ksp") version "2.0.21-1.0.28"
// 2. Apply KProxyable
id("io.github.elianfabian.kproxyable") version "1.0.5"
}The KProxyable plugin automatically:
kproxyable-runtime dependency to commonMain.kproxyable-processor for all Main and Test configurations (supporting cross-module discovery and unit tests).If you prefer to manage KSP and runtime dependencies manually:
repositories {
mavenCentral()
}
dependencies {
implementation("io.github.elianfabian:kproxyable-runtime:1.0.5")
ksp("io.github.elianfabian:kproxyable-processor:1.0.5")
kspTest("io.github.elianfabian:kproxyable-processor:1.0.5")
}Annotate any public or internal interface with @KProxyable:
import com.elianfabian.kproxyable.KProxyable
@KProxyable
interface MyService {
fun doSomething(id: Int, name: String): String
suspend fun fetchData(query: String): List<String>
var isActive: Boolean
}The ProxyHandler is responsible for intercepting all calls to the proxy instance:
class MyHandler : ProxyHandler {
override fun onCall(function: FunctionDescriptor, args: List<Any?>): Any? {
println("Calling ${function.name} with $args")
return "Intercepted result"
}
override suspend fun onSuspendCall(function: FunctionDescriptor, args: List<Any?>): Any? {
return listOf("Async", "Result")
}
// Handle properties, equals, hashCode, and toString...
}Use the create factory method to instantiate your intercepted interface:
// In JVM projects
val service = KProxyJvm.create<MyService>(MyHandler())
// In JS projects
val service = KProxyJs.create<MyService>(MyHandler())KProxyable provides optimized entry points depending on your project type:
Use KProxyJvm for standard JVM or Android applications. It uses a lightweight ServiceLoader mechanism to discover generated registries.
Use KProxyJs for Kotlin/JS projects. It leverages global scope hooks to link generated code without reflection.
In a KMP project, you can define a shared entry point in commonMain using an expect object:
// commonMain
@KProxyRegistry
expect object MyProxyFactory : KProxyFactory
// usage
val service = MyProxyFactory.create<MyService>(MyHandler())KSP will automatically generate the actual implementation in your platform-specific source sets, aggregating all @KProxyable interfaces found in your project and its dependencies.
Instead of using @KProxyable everywhere, you can create your own domain-specific annotations:
@Target(AnnotationTarget.CLASS)
@KProxyable // This makes @MyClient a proxy trigger
annotation class MyClient
@MyClient
interface UserApi {
fun getUser(id: String): User
}KProxyable is a showcase of AI-Collaborative Engineering.
The implementation of this library, including its KSP processor and complex multi-platform CI/CD pipeline, was primarily driven by AI assistants working under human architectural guidance. This project serves as an experiment in how modern AI tools can accelerate the development of professional-grade, specialized infrastructure for the Kotlin ecosystem.
This project is licensed under the MIT License - see the LICENSE file for details.