Skip to content
CAI
Software that uses CAICheck a score

skydoves/Balloon

62.1

Adequate · 25 September 2026

10.5k

lines of production code

Kotlin

primary language

4

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is the Balloon library, a cross-platform tooltip component that has been migrated from a legacy Android View-based implementation to a Kotlin Multiplatform Compose UI. It provides a unified API for rendering balloons with configurable positioning, animations, and overlays across Android, iOS, Desktop, and Web targets. The repository includes comprehensive demo applications and a pixel-parity harness to verify visual consistency and functional parity across all supported platforms.

How it got here

2019 — Compose Multiplatform migration

6 changes.

The project was restructured from an Android-only application into a Kotlin Multiplatform library supporting Android, Desktop, iOS, and Web. This period involved initializing the new Compose-based architecture, migrating build tooling to Kotlin DSL, and removing legacy demo code while fixing Android popup positioning behavior.

2022–2023 — Build configuration and release preparation

4 changes.

This period focused on updating the build infrastructure, including raising SDK targets and standardizing Maven publication logic for version management. Efforts also included organizing license headers and generating baseline profiles to optimize the library's runtime performance.

2026 — Compose Multiplatform demo expansion

4 changes.

This period focused on expanding the Balloon library's demonstration capabilities by adding new demo applications for Android, Desktop, WebAssembly, and iOS targets. The work included implementing a pixel-parity harness for Android and establishing the initial iOS app shell to support Kotlin Multiplatform integration. Additionally, shared sample screens were introduced to provide interactive playgrounds and visual comparisons across all supported platforms.

Features

Add desktop and WebAssembly demo applications for Balloon Compose Multiplatform

New demo applications have been added for both desktop and WebAssembly targets, allowing users to run and test the Balloon library on these platforms. The desktop app (desktopApp) launches a Compose window displaying the sample UI, while the wasmApp provides a browser-based entry point that renders the sample app within the DOM. These additions support the promotion of the Compose Multiplatform implementation to the balloon artifact for version 2.0.0.

desktopApp, wasmApp · high confidence

Initial iOS app shell for Kotlin Multiplatform integration

The iosApp directory now contains a complete Xcode project structure, including the project file, configuration, and Swift UI entry points. This setup enables the iOS application to embed and sign a Kotlin framework via a Gradle build phase, allowing SwiftUI views to host the shared Kotlin Compose UI through a UIViewControllerRepresentable wrapper.

iosApp · high confidence

New Compose Multiplatform demo app with pixel-parity harness

A new Android demo application (\Balloon KMP Demo\) has been added to showcase the Compose Multiplatform implementation of the Balloon library. This includes a main activity (\KmpBalloonActivity\) that hosts the shared \BalloonSampleApp\ composable, and a dedicated pixel-parity harness (\KmpParityActivity\) that renders specific balloon configurations (alignments, arrow positions, sizes, overlays) using identical test cases to the existing View-based demo. This allows for direct visual comparison and verification that the Compose Multiplatform version behaves identically to the legacy Android implementation.

androidApp · high confidence

New Compose Multiplatform sample screens: Labs playground and Glass tooltip demo

The shared sample module now includes a comprehensive interactive playground (Labs) that allows users to adjust every balloon configuration knob—such as arrow geometry, body styling, sizing, placement, animations, and overlays—in real time, and a new Glass tooltip demo that uses the Cloudy library to render translucent, blurred tooltips that reveal the content underneath. These screens are integrated into the shared sample app entry point, providing a unified, cross-platform demonstration of the library's capabilities.

samples-shared · high confidence

Repository initialization with Compose Multiplatform documentation and tooling

The repository has been initialized with version 2.0.1 of Balloon, a Compose Multiplatform tooltip library supporting Android, iOS, Desktop, and Web. The diff establishes the project's documentation structure, including a comprehensive README detailing the new Compose-based API (replacing the legacy View/PopupWindow implementation), a migration guide for 1.x users, and a MkDocs configuration for the site. It also adds standard contributor guidelines (Code of Conduct, Contributing) and configures development tooling such as Renovate for dependency updates, CodeRabbit for code reviews, and a \.gitignore\ that excludes per-user IDE and Xcode state files.

(repo-wide) · high confidence

Removals

Removed legacy demo code and utilities

The legacy demo implementation files, including BalloonUtils, MainActivity, and the recycler sample components (SampleAdapter, SampleUtils, SampleViewHolder), have been removed from the app source. This cleanup eliminates the old sample codebase that previously demonstrated balloon usage via utility methods and a main activity with a sample list.

app/src/main/java · high confidence

Behavioural changes

Add XML license header format and reorganize license files

The Spotless configuration now supports applying license headers to XML files, using a new license template located at spotless/spotless.license.xml. The previous Kotlin license template has been moved into the spotless directory (renamed from spotless.license.kt to spotless/spotless.license.kt) to keep license resources organized.

spotless · high confidence

Balloon popup positioning now respects full window bounds on Android

The Android implementation of the Balloon popup layer now disables clipping in its popup properties, ensuring that the popup uses the full window bounds (including system bars) for positioning calculations. This aligns the popup's coordinate space with the anchor's \boundsInWindow()\ measurements, fixing issues where balloons near the bottom would incorrectly flip above their anchor or where the overlay scrim would stop at the status bar instead of covering the entire screen.

balloon · high confidence

Release 2.0.1 configuration and SDK updates

The build configuration in buildSrc has been updated to version 2.0.1, with the minimum SDK raised to 23 and both compile and target SDKs set to 36. A separate demo compile SDK of 37 is defined to support the liquid glass tooltip demo while keeping the published library on SDK 36.

buildSrc · high confidence

Removal of Android build configuration files

The app module no longer includes the .gitignore file (previously excluding the /build directory) and the proguard-rules.pro file (previously containing commented-out ProGuard configuration rules). This indicates a change in how the Android application handles version control exclusions and code shrinking/obfuscation settings.

app · high confidence

Standardized Maven publication versioning logic

A new Gradle script (publish-module.gradle.kts) has been introduced to centralize Maven publication configuration. This script applies the com.vanniktech.maven.publish plugin and dynamically determines the library version based on the SNAPSHOT environment variable, allowing users to easily toggle between snapshot and release versioning during the build process.

scripts · high confidence

Test coverage

Added baseline profile generation for Balloon 2.0.0

A new BaselineProfileGenerator test has been added to the benchmark module to record classes and methods used by the Balloon library during runtime. The generator exercises the library by opening and dismissing balloons of every kind offered by the demo, including each entry animation, each highlight animation, and both overlay shapes, ensuring the baseline profile captures the actual usage patterns rather than just startup code.

benchmark/src/main/kotlin · high confidence

Dependencies

Gradle wrapper upgraded to version 9.8.0

The project's Gradle wrapper has been updated from version 5.1.1 to 9.8.0. This change ensures that builds use the newer Gradle distribution, which may include performance improvements, new features, and bug fixes compared to the previous version.

gradle · high confidence

Migrate to Kotlin Multiplatform and Compose Multiplatform

The project has been restructured from a single Android application into a Kotlin Multiplatform (KMP) library and demo suite. The core \:balloon\ module is now a KMP library targeting Android, Desktop (JVM), iOS, and WebAssembly (WasmJs), replacing the previous Android-only implementation. The build system has migrated from Groovy to Kotlin DSL and adopted the Version Catalog pattern (defined in \gradle/libs.versions.toml\) for dependency management. Key dependencies include Kotlin 2.4.10, Android Gradle Plugin 9.3.0-alpha01, and Compose Multiplatform 1.10.3. The previous Android demo app has been replaced by dedicated KMP demo applications for Android (\:androidApp\), Desktop (\:desktopApp\), and Web (\:wasmApp\), along with a shared sample module (\:samples-shared\) that re-exports the library for these platforms.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.

Score

  • CAI 42 → 62 (+19.8)
  • Rubric changed (rubric-2026.08.15 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 97 → 94 (-2.6)
  • Architecture 94 → 100 (+5.7)
  • Maturity 50 → 57 (+7.5)
  • Readiness 34 → 56 (+21.0)
  • Security 31 → 64 (+33.0)

Resolved (38)

  • Coverage not measured — test suite did not build
  • Dimension evaluation failed
  • Duplicated block (11 lines × 2) (balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonModifier.kt)
  • Duplicated block (14 lines × 2) (app/src/main/kotlin/com/skydoves/balloondemo/ComposeActivity.kt)
  • Duplicated block (22 lines × 2) (app/src/main/kotlin/com/skydoves/balloondemo/ComposeActivity.kt)
  • Duplicated block (31 lines × 2) (app/src/main/kotlin/com/skydoves/balloondemo/ComposeActivity.kt)
  • Duplicated block (8 lines × 2) (balloon/src/main/kotlin/com/skydoves/balloon/Balloon.kt)
  • Duplicated block (9 lines × 2) (balloon/src/main/kotlin/com/skydoves/balloon/overlay/BalloonAnchorOverlayView.kt)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • …and 18 more

New (45)

  • Ambiguous intent: show and update have identical signatures and likely similar behavior (showing the balloon at a specific alignment). It is unclear if update implies modifying an already visible balloon versus show which might imply a fresh display or state transition.
  • BalloonKt.BalloonContent (cognitive 25) (balloon/src/commonMain/kotlin/com/skydoves/balloon/Balloon.kt)
  • BalloonKt.BalloonContent (cyclomatic 28) (balloon/src/commonMain/kotlin/com/skydoves/balloon/Balloon.kt)
  • BalloonPopupKt.BalloonPopupLayer (cognitive 16) (balloon/src/commonMain/kotlin/com/skydoves/balloon/BalloonPopup.kt)
  • BalloonPopupPositionProvider.calculatePosition (cognitive 60) (balloon/src/commonMain/kotlin/com/skydoves/balloon/BalloonPopup.kt)
  • BalloonPopupPositionProvider.calculatePosition (cyclomatic 36) (balloon/src/commonMain/kotlin/com/skydoves/balloon/BalloonPopup.kt)
  • BalloonPopupPositionProvider.resolveArrowCenter (cyclomatic 16) (balloon/src/commonMain/kotlin/com/skydoves/balloon/BalloonPopup.kt)
  • BalloonShapeBuilderKt.buildBalloonPath (cyclomatic 18) (balloon/src/commonMain/kotlin/com/skydoves/balloon/BalloonShapeBuilder.kt)
  • Dependency hygiene PARTLY measured — Maven/Gradle declarations read, no dependency graph resolved
  • Documentation: no project overview (README.md)
  • Duplicate intent: Both methods configure the visual border/stroke of the balloon. 'Stroke' and 'Border' are semantically equivalent in this context, leading to confusion about which to use.
  • Duplicated block (13 lines × 2) (samples-shared/src/commonMain/kotlin/com/skydoves/balloon/sample/BalloonDemoScreen.kt)
  • Duplicated block (5 lines × 3) (balloon/src/commonMain/kotlin/com/skydoves/balloon/BalloonShapeBuilder.kt)
  • FileTooLong: balloon/Balloon.kt (balloon/src/commonMain/kotlin/com/skydoves/balloon/Balloon.kt)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • High: security finding (details withheld)
  • …and 25 more

Changes since last survey

  • 47 commits — 41 feature/other, 6 fixes

By area

  • gradle/libs.versions.toml — 10 commits
  • (root) — 7 commits
  • balloon/src — 7 commits
  • (repo) — 4 commits
  • .github/workflows — 4 commits
  • androidApp/src — 2 commits
  • balloon-compose-multiplatform/src — 2 commits
  • balloon/api — 2 commits
  • docs/legacy-view — 2 commits
  • gradle/wrapper — 2 commits
  • samples-shared/src — 2 commits
  • art/thumbnail.png — 1 commit
  • docs/migration.md — 1 commit
  • iosApp/iosApp.xcodeproj — 1 commit

Notable commits

  • fix: Fix animation and dismissal regressions found auditing 2.0.0 against 1.7.6
  • fix: Fix hit testing, the overlay padding ring and shared placement state
  • fix: Fix the RTL first-frame arrow edge and correct docs flagged in review
  • fix: Merge pull request #1016 from skydoves/fix/revert-cmp-1.12.0
  • fix: Merge pull request #1017 from skydoves/fix/verify-legacy-issues
  • fix: Revert Compose Multiplatform to 1.10.3
  • change: Add TikTok to the Who's using list (#1026)
  • change: Add a Labs screen that drives every builder setter live
  • change: Add a golden screenshot suite for the rendering surface
  • change: Add a liquid glass tooltip demo built on Cloudy (#1020)
  • change: Add a pixel-parity harness to the demo apps
  • change: Add repository art: CodeRabbit logo and a multiplatform preview (#1018)
  • change: Add unit and UI tests for the multiplatform balloon
  • change: Bring the GitHub Actions up to date
  • change: Cover the derive round trip
  • change: Document the golden screenshot workflow
  • change: Drop --scan from the CI build
  • change: Drop --scan from the release build too
  • change: Generate a baseline profile for 2.0.0
  • change: Make the Renovate AGP freeze actually match
  • …and 27 more

Architecture

  • Containers 0 added · 0 removed · contexts 3 added · 0 removed · edges 2 added · 0 removed

Added bounded contexts (3)

  • androidApp
  • balloon
  • samples-shared

Added dependency edges (2)

  • androidApp → balloon
  • samples-shared → balloon

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

skydoves/Balloon was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 25 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 60b3a940aa346baabf22b271187860ecf84be535 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-a9cd699f3cd5.