We're excited to announce KRelay v2.0.0, a major update that brings powerful new capabilities while maintaining 100% backward compatibility.
Create isolated KRelay instances for true module independence:
// Create isolated instances
val rideKRelay = KRelay.create("Rides")
val foodKRelay = KRelay.create("Food")
// Each module has independent registry - no conflicts!
rideKRelay.register<ToastFeature>(RideToastImpl())
foodKRelay.register<ToastFeature>(FoodToastImpl())If you're building a "Super App" (like Grab or Gojek) with multiple independent modules, v2.0 solves the feature name conflict problem:
Before (v1.x):
// Problem: Both modules use same feature name
KRelay.register<ToastFeature>(RideToastImpl())
KRelay.register<ToastFeature>(FoodToastImpl()) // ❌ Overwrites!After (v2.0):
// Solution: Each module has its own instance
val rideKRelay = KRelay.create("Rides")
val foodKRelay = KRelay.create("Food")
rideKRelay.register<ToastFeature>(RideToastImpl())
foodKRelay.register<ToastFeature>(FoodToastImpl()) // ✅ No conflict!Perfect integration with dependency injection frameworks:
// Koin module
val rideModule = module {
single { KRelay.create("RideModule") }
viewModel { RideViewModel(krelay = get()) }
}
// ViewModel
class RideViewModel(private val krelay: KRelayInstance) : ViewModel() {
fun bookRide() {
krelay.dispatch<ToastFeature> { it.show("Booking...") }
}
}Use the builder pattern for custom configuration:
val instance = KRelay.builder("MyModule")
.maxQueueSize(50)
.actionExpiry(60_000L)
.debugMode(true)
.build()- Duplicate Scope Name Detection: Get warnings in debug mode when creating instances with duplicate names
- Input Validation: Builder parameters validated with clear error messages
- Better Error Messages: Know exactly what went wrong
- 10 New Isolation Tests: Comprehensive testing of multi-instance scenarios
- 100% Test Pass Rate: All 15 instance tests passing
- <5% Performance Overhead: Instance API is just as fast as singleton
- ~800 bytes per Instance: Minimal memory footprint
- Migration Guide - How to upgrade from v1.x
- Super App Example - Complete architecture guide
- DI Integration - Koin and Hilt examples
- Technical Review - Deep dive analysis
Good news: Migration is optional!
- ✅ No Breaking Changes: All v1.x code works without modification
- ✅ Incremental Adoption: Migrate at your own pace
- ✅ Simple Apps: Can continue using singleton API
- ✅ New Projects: Start with instance API for better architecture
// Gradle (build.gradle.kts)
dependencies {
implementation("dev.brewkits:krelay:2.0.0")
}// Still works exactly as before
KRelay.dispatch<ToastFeature> { it.show("Hello!") }// Create instance
val krelay = KRelay.create("MyScope")
// Use it
krelay.dispatch<ToastFeature> { it.show("Hello!") }v2.0 uses a Facade Pattern:
- Singleton API delegates to internal
defaultInstance - Each instance has isolated registry, queue, and lock
- Per-instance configuration
- Thread-safe with fine-grained locking
Highly Recommended for:
- Super Apps with multiple independent modules
- Projects using DI (Koin, Hilt)
- Multi-team organizations
- Large-scale apps with modular architecture
Optional for:
- Simple single-module apps
- Small to medium projects
- Existing apps with singleton API (works fine)
- Instance creation: ~0.4ms
- Dispatch overhead: +2% vs singleton (negligible)
- Memory per instance: ~800 bytes
- 50 instances = ~40KB total
Thank you to the Kotlin Multiplatform community for feedback and support!
Full Changelog: https://github.com/brewkits/KRelay/blob/main/CHANGELOG.md