Skip to content

Sidekick

A Kotlin Multiplatform debug overlay SDK for Android, iOS, Desktop (JVM), and Web (JS / Wasm).

Android iOS Desktop Web JS Web Wasm License Kotlin Compose

Sidekick adds a floating debug panel to your app during development — network inspector, log viewer, preferences editor, custom screens. In release builds, a no-op module strips the overlay entirely with zero overhead.


Why Sidekick

  • One panel, many tools — built-in network inspector, log viewer, typed preferences editor, custom Composables.
  • Pluggable — implement SidekickPlugin to add anything else.
  • Zero release costcore:noop replaces the overlay with a passthrough composable, and network-monitor:noop / log-monitor:noop strip the SQLDelight recording layer; release binaries don't contain a single byte of Sidekick UI or database code.
  • Compose Multiplatform — single UI codebase across Android, iOS, Desktop, and Web.
  • Visibility is yours to control — Sidekick renders the panel; the host app decides when to show it (FAB, shake gesture, build-type check, anything).

Built-in Plugins

Plugin What it does
Network Monitor Captures and displays all HTTP traffic via Ktor (or any client via NetworkMonitorStore).
Log Monitor Displays app logs with level filtering and search (Kermit built-in, any SDK via LogCollector).
Preferences Exposes typed settings in the panel — KSP code generation or manual DataStore bridging.
Custom Screens Wraps any Composable as a first-class debug screen.

Quick Example

@Composable
fun App() {
    val networkPlugin = remember { NetworkMonitorPlugin() }
    val plugins = remember { listOf(networkPlugin) }

    MaterialTheme {
        var sidekickVisible by remember { mutableStateOf(false) }
        Scaffold(
            floatingActionButton = {
                FloatingActionButton(onClick = { sidekickVisible = true }) {
                    Icon(Icons.Default.BugReport, contentDescription = "Open Sidekick")
                }
            },
        ) {
            Box(Modifier.fillMaxSize().padding(it)) {
                // your app content
                AnimatedVisibility(visible = sidekickVisible) {
                    Sidekick(
                        plugins = plugins,
                        actions = {
                            IconButton(onClick = { sidekickVisible = false }) {
                                Icon(Icons.Default.Close, contentDescription = "Close")
                            }
                        },
                    )
                }
            }
        }
    }
}

A FAB appears in the bottom-right corner. Tap it to open the Sidekick panel.


Ready to add Sidekick to your project? Start with Installation.


Credits

The demo app uses data from PokéAPI — a free, open RESTful Pokémon API. See pokeapi.co/about for license and usage details.