Kotlin Multiplatform BLE library for iOS, Android, macos, windows and javascript
Release Date: TBD 2026
Status: β Ready for Release
Blue Falcon 3.0.0 represents a major architectural evolution of the library, introducing a plugin-based engine system while maintaining full backward compatibility with 2.x applications.
Blue Falcon now separates core functionality from platform implementations, enabling:
val blueFalcon = BlueFalcon {
engine = AndroidBlueFalconEngine(context)
install(LoggingPlugin) {
level = LogLevel.DEBUG
}
install(RetryPlugin) {
maxRetries = 3
}
}
Core library is now split into focused modules:
| Module | Purpose | Maven Coordinates |
|---|---|---|
| Core | Platform-agnostic API | dev.bluefalcon:blue-falcon-core:3.0.0 |
| Android Engine | Android BLE implementation | dev.bluefalcon:blue-falcon-engine-android:3.0.0 |
| iOS Engine | iOS CoreBluetooth | dev.bluefalcon:blue-falcon-engine-ios:3.0.0 |
| macOS Engine | macOS CoreBluetooth | dev.bluefalcon:blue-falcon-engine-macos:3.0.0 |
| JS Engine | Web Bluetooth API | dev.bluefalcon:blue-falcon-engine-js:3.0.0 |
| Windows Engine | Windows WinRT BLE | dev.bluefalcon:blue-falcon-engine-windows:3.0.0 |
| RPI Engine | Raspberry Pi support | dev.bluefalcon:blue-falcon-engine-rpi:3.0.0 |
| Legacy API | 2.x compatibility layer | dev.bluefalcon:blue-falcon-legacy:3.0.0 |
Three powerful plugins ship with 3.0:
1. LoggingPlugin - Debug BLE operations
install(LoggingPlugin) {
level = LogLevel.DEBUG
logConnections = true
logGattOperations = true
}
2. RetryPlugin - Automatic retry with exponential backoff
install(RetryPlugin) {
maxRetries = 3
initialDelay = 500.milliseconds
backoffMultiplier = 2.0
}
3. CachingPlugin - Cache GATT services and characteristics
install(CachingPlugin) {
cacheSize = 10
ttl = 5.minutes
}
lifecycleScope.launch {
// Suspend functions for clean async code
blueFalcon.scan()
blueFalcon.connect(peripheral)
blueFalcon.discoverServices(peripheral)
// StateFlow for reactive updates
blueFalcon.peripherals.collect { devices ->
updateUI(devices)
}
}
Zero code changes required for existing 2.x applications:
// Your existing 2.x code works as-is!
val blueFalcon = BlueFalcon(log = null, ApplicationContext())
blueFalcon.delegates.add(myDelegate)
blueFalcon.scan()
Simply add the blue-falcon-legacy dependency alongside your engine.
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation("dev.bluefalcon:blue-falcon-core:3.0.0")
// Optional plugins
implementation("dev.bluefalcon:blue-falcon-plugin-logging:3.0.0")
implementation("dev.bluefalcon:blue-falcon-plugin-retry:3.0.0")
implementation("dev.bluefalcon:blue-falcon-plugin-caching:3.0.0")
}
}
val androidMain by getting {
dependencies {
implementation("dev.bluefalcon:blue-falcon-engine-android:3.0.0")
}
}
val iosMain by getting {
dependencies {
implementation("dev.bluefalcon:blue-falcon-engine-ios:3.0.0")
}
}
}
}
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
implementation("dev.bluefalcon:blue-falcon-core:3.0.0")
implementation("dev.bluefalcon:blue-falcon-legacy:3.0.0")
}
}
val androidMain by getting {
dependencies {
implementation("dev.bluefalcon:blue-falcon-engine-android:3.0.0")
}
}
}
}
// Reactive peripheral discovery
blueFalcon.peripherals.collect { devices ->
println("Found ${devices.size} devices")
devices.forEach { device ->
println(" - ${device.name} (${device.uuid})")
}
}
// Monitor Bluetooth adapter state
blueFalcon.managerState.collect { state ->
when (state) {
BluetoothManagerState.PoweredOn -> startScanning()
BluetoothManagerState.PoweredOff -> showEnableBluetoothDialog()
BluetoothManagerState.Unauthorized -> requestPermissions()
else -> {}
}
}
All BLE operations are now suspend functions for cleaner async code:
suspend fun connectToDevice(device: BluetoothPeripheral) {
try {
blueFalcon.connect(device)
blueFalcon.discoverServices(device)
val service = device.services.first()
val characteristic = service.characteristics.first()
blueFalcon.readCharacteristic(device, characteristic)
val data = characteristic.value
println("Data: ${data?.decodeToString()}")
} catch (e: BluetoothException) {
println("Error: ${e.message}")
}
}
Extend Blue Falcon with your own plugins:
class MyPlugin(private val config: Config) : BlueFalconPlugin {
class Config : PluginConfig() {
var enabled: Boolean = true
}
override fun install(client: BlueFalconClient, config: PluginConfig) {
println("MyPlugin installed")
}
override suspend fun onBeforeConnect(call: ConnectCall): ConnectCall {
println("Connecting to ${call.peripheral.name}")
return call
}
override suspend fun onAfterConnect(call: ConnectCall, result: Result<Unit>) {
result.onSuccess { println("Connected!") }
result.onFailure { println("Failed!") }
}
}
// Use it
val blueFalcon = BlueFalcon {
engine = AndroidBlueFalconEngine(context)
install(MyPlugin(MyPlugin.Config()))
}
Combine multiple plugins:
val blueFalcon = BlueFalcon {
engine = AndroidBlueFalconEngine(context)
// Debug logging in development
if (BuildConfig.DEBUG) {
install(LoggingPlugin) {
level = LogLevel.DEBUG
}
}
// Always retry failed operations
install(RetryPlugin) {
maxRetries = 3
}
// Cache for performance
install(CachingPlugin) {
cacheSize = 20
}
}
Create custom engines for specialized hardware:
class CustomBleEngine : BlueFalconEngine {
override val scope = CoroutineScope(Dispatchers.Default)
override val peripherals = MutableStateFlow<Set<BluetoothPeripheral>>(emptySet())
override val managerState = MutableStateFlow(BluetoothManagerState.PoweredOn)
override var isScanning = false
override suspend fun scan(filters: List<ServiceFilter>) {
// Custom BLE stack implementation
}
// Implement other methods...
}
// Use it
val blueFalcon = BlueFalcon(CustomBleEngine())
If using the blue-falcon-legacy module, there are zero breaking changes. All 2.x code continues to work.
If adopting the modern 3.0 APIs:
// 2.x
import dev.bluefalcon.BlueFalcon
// 3.0
import dev.bluefalcon.core.BlueFalcon
import dev.bluefalcon.plugins.logging.LoggingPlugin
// 2.x
BlueFalcon(log, context, autoDiscover)
// 3.0
BlueFalcon {
engine = AndroidBlueFalconEngine(context)
}
// 2.x - Delegates
blueFalcon.delegates.add(object : BlueFalconDelegate {
override fun didDiscoverDevice(device: BluetoothPeripheral) { }
})
// 3.0 - StateFlow
blueFalcon.peripherals.collect { devices -> }
// 2.x
blueFalcon.scan()
// 3.0
lifecycleScope.launch {
blueFalcon.scan()
}
examples/KotlinMP-Example - Updated to demonstrate 3.0 APIsexamples/Plugin-Example - New example showing plugin usageexamples/README.md - How to run examplesautoConnect parameter works only on Android, no-op on other platformsrefreshGattCache() is Android-specificrequestConnectionPriority() is no-op on iOS/macOSbluefalcon-windows.dll in library pathSpecial thanks to:
| Version | Release Date | Major Changes |
|---|---|---|
| 3.0.0 | TBD 2026 | Plugin architecture, modular engines, modern APIs |
| 2.0.0 | 2024 | Kotlin 2.0, improved multiplatform support |
| 1.x.x | 2019-2023 | Initial releases, platform support |
Blue Falcon is released under the Apache License 2.0.
See LICENSE for details.
Ready to upgrade? Check out our Migration Guide for step-by-step instructions!
New to Blue Falcon? Start with the API Reference and explore the examples/ directory.
Happy coding with Blue Falcon 3.0! π¦ β¨