{"id":49879651,"url":"https://github.com/spongycode/debukker","last_synced_at":"2026-05-15T13:39:54.032Z","repository":{"id":334199755,"uuid":"1139642057","full_name":"spongycode/debukker","owner":"spongycode","description":"Cross-platform in-app debugging toolkit for Kotlin Multiplatform (KMP) 🐛","archived":false,"fork":false,"pushed_at":"2026-02-21T08:11:08.000Z","size":340,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-21T13:49:26.527Z","etag":null,"topics":["compose-multiplatform","debugging","kmp","kotlin-multiplatform","ktor","mock-server","network-inspector"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spongycode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-22T08:16:52.000Z","updated_at":"2026-02-21T08:11:11.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/spongycode/debukker","commit_stats":null,"previous_names":["spongycode/debukker"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/spongycode/debukker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spongycode%2Fdebukker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spongycode%2Fdebukker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spongycode%2Fdebukker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spongycode%2Fdebukker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spongycode","download_url":"https://codeload.github.com/spongycode/debukker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spongycode%2Fdebukker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33068889,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T11:35:32.926Z","status":"ssl_error","status_checked_at":"2026-05-15T11:35:31.362Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compose-multiplatform","debugging","kmp","kotlin-multiplatform","ktor","mock-server","network-inspector"],"created_at":"2026-05-15T13:39:53.557Z","updated_at":"2026-05-15T13:39:54.019Z","avatar_url":"https://github.com/spongycode.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Debukker 🐛\n\nA powerful, plug-and-play Network Debugger and Interceptor for Kotlin Multiplatform (KMP) projects.\n\n## Features\n- **Zero Release Overhead**: Implements a Facade pattern allowing you to completely strip the library from your production builds across all KMP targets.\n- **Draggable Debug Button**: A floating action button that persists its position across screens.\n- **Network Logging**: View all Ktor requests and responses in real-time with detailed inspection.\n- **Advanced Mocking**: Override status codes, bodies, headers, and simulate network conditions.\n- **Environment Switcher**: Dynamically switch API base URLs without rebuilding.\n- **Preference Manager**: View and edit on-device key-value storage (DataStore/Settings) in real-time.\n- **Cross-Platform**: Android, iOS, Desktop (JVM), and Web (JS \u0026 WASM).\n\n## Detailed Capabilities\n\n### Network Logging\n- **Real-time Monitoring**: Intercept and view every Ktor network request/response.\n- **Detailed Inspection**: Dedicated screens for Headers, Query Parameters, and Request/Response bodies.\n- **cURL Support**: Export any request as a standard cURL command for easy reproduction in terminals.\n- **Filtering**: Search transactions by URL or method using regex or simple text.\n\n### Network Mocking \u0026 Interception\n- **Response Mocks**: Map specific URL patterns to custom status codes, bodies, and headers.\n- **Request modifiers**: Inject or override headers for outgoing requests based on URL patterns.\n- **Global Headers**: Add headers (like Auth tokens or App versions) globally to all outgoing requests.\n- **Latency Simulation**: Artificial network throttling to test app behavior under slow connections.\n- **Offline Mode**: One-tap toggle to block all network traffic.\n- **Timeouts**: Override default request, connect, and socket timeouts on the fly.\n\n### Environment Management\n- **One-Tap Switching**: Toggle between Production, Pre-prod, and Local environments.\n- **Custom URLs**: Enter and save a completely custom base URL for specific testing scenarios.\n- **Persistence**: Your chosen environment persists across app restarts.\n\n### Preference Management\n- **Key-Value Discovery**: Automatically lists all values stored in your app's local preferences.\n- **Searchable**: Quickly find specific keys in apps with large preference sets.\n- **Live Editing**: Modify values on the fly to test different user states.\n- **Management**: Add new keys or delete existing ones directly from the debug menu.\n\n## Release-Safe Integration (Facade Pattern)\n\nTo ensure Debukker's UI and logic are fully removed from your release builds, we strongly recommend against adding it to `commonMain`. Instead, use the **Facade Pattern** as demonstrated in the `:sample` project.\n\n### 1. Create a Facade in `commonMain`\nCreate an object in your shared module to hold references to the Debukker components. In release builds, these will be no-ops.\n\n```kotlin\n// commonMain/src/.../DebugFacade.kt\nobject DebugFacade {\n    var DebukkerUI: @Composable () -\u003e Unit = {}\n    var httpClientFactory: () -\u003e HttpClient = { HttpClient() }\n}\n```\n\nUse this facade in your application:\n```kotlin\n// App.kt\n@Composable\nfun App() {\n    val client = remember { DebugFacade.httpClientFactory() }\n    \n    Box(modifier = Modifier.fillMaxSize()) {\n        // Your App UI...\n        \n        // This will be a no-op in release builds, but will render a DraggableDebugButton in debug builds\n        DebugFacade.DebukkerUI()\n    }\n}\n```\n\n### 2. Configure Dependencies (`build.gradle.kts`)\nAdd the library only to specific debug configurations. For Android, use `debugImplementation`. For other platforms, use a Gradle project property (e.g., `isDebug`) combined with `srcDir` re-routing.\n\n```kotlin\nval isDebug = project.hasProperty(\"isDebug\")\n\nkotlin {\n    sourceSets {\n        val jvmMain by getting {\n            dependencies { if (isDebug) implementation(\"com.spongycode:debukker:\u003cversion\u003e\") }\n            // Point to different source sets based on build type\n            kotlin.srcDir(if (isDebug) \"src/nonAndroidDebug/kotlin\" else \"src/nonAndroidRelease/kotlin\")\n        }\n        val iosMain by creating {\n            dependencies { if (isDebug) implementation(\"com.spongycode:debukker:\u003cversion\u003e\") }\n            kotlin.srcDir(if (isDebug) \"src/nonAndroidDebug/kotlin\" else \"src/nonAndroidRelease/kotlin\")\n        }\n        // ... (Repeat for jsMain, wasmJsMain, etc.)\n    }\n}\n\ndependencies {\n    debugImplementation(\"com.spongycode:debukker:\u003cversion\u003e\")\n}\n```\n\n### 3. Initialize on Android\nCreate a `DebugInitializer` object in `src/androidDebug/kotlin` and `src/androidRelease/kotlin`.\n\n**`src/androidDebug/kotlin/.../DebugInitializer.kt`**\n```kotlin\nimport com.spongycode.debukker.preferences.initializePreferences\nimport com.spongycode.debukker.ui.DraggableDebugButton\nimport com.spongycode.debukker.network.createDebugHttpClient\n\nobject DebugInitializer {\n    fun init(context: Context) {\n        initializePreferences(context)\n        DebugFacade.DebukkerUI = { DraggableDebugButton() }\n        DebugFacade.httpClientFactory = { createDebugHttpClient() }\n    }\n}\n```\n\n**`src/androidRelease/kotlin/.../DebugInitializer.kt`**\n```kotlin\nobject DebugInitializer {\n    fun init(context: Context) { /* No-op */ }\n}\n```\n\nCall `DebugInitializer.init(this)` inside your `MainActivity.onCreate`.\n\n### 4. Initialize on Non-Android Targets\nCreate a top-level `initDebukker()` function in `src/nonAndroidDebug/kotlin` and `src/nonAndroidRelease/kotlin`.\n\n**`src/nonAndroidDebug/kotlin/.../DebukkerInit.kt`**\n```kotlin\nimport com.spongycode.debukker.ui.DraggableDebugButton\nimport com.spongycode.debukker.network.createDebugHttpClient\n\nfun initDebukker() {\n    DebugFacade.DebukkerUI = { DraggableDebugButton() }\n    DebugFacade.httpClientFactory = { createDebugHttpClient() }\n}\n```\n\n**`src/nonAndroidRelease/kotlin/.../DebukkerInit.kt`**\n```kotlin\nfun initDebukker() { /* No-op */ }\n```\n\nCall `initDebukker()` inside your `main()` or `MainViewController()` definitions before launching your Compose app.\n\n## Advanced: Custom HttpClient Integration\n\nIf you already have a pre-configured `HttpClient` and don't want to use the `createDebugHttpClient()` helper, you can manually install the `DebugNetworkPlugin`:\n\n```kotlin\nval myClient = HttpClient {\n    // Your existing configuration...\n    install(ContentNegotiation) { json() }\n    \n    // Install the Debukker plugin manually\n    install(DebugNetworkPlugin) \n}\n```\n\nThis ensures Debukker intercepts all traffic from your existing client without forcing a new instance upon your application.\n\n## Running the Sample\n- **Android**: `./gradlew :sample:installDebug`\n- **iOS**: Open `sample/iosApp/iosApp.xcodeproj` in Xcode (ensure you pass `-PisDebug=true` to your Gradle build phases if testing Debug mode).\n- **Desktop**: `./gradlew :sample:run -PisDebug=true`\n- **Web (WASM)**: `./gradlew :sample:wasmJsBrowserDevelopmentRun -PisDebug=true`\n- **Web (JS)**: `./gradlew :sample:jsBrowserDevelopmentRun -PisDebug=true`\n\n\n## Contributing\nFeel free to contribute to this project by submitting issues, pull requests, or providing valuable feedback. Your contributions are always welcome!\n\n## License\nDebukker is released under the [MIT License](https://opensource.org/licenses/MIT). Feel free to modify or add to this list based on the specific features of your app.\n\n## Happy coding! 🎉👩‍💻👨‍💻\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspongycode%2Fdebukker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspongycode%2Fdebukker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspongycode%2Fdebukker/lists"}