# Corbind: turning Android widget callbacks into Flow and Channel bindings

> Corbind is a set of Kotlin libraries that wrap the callback APIs of Android platform widgets, AndroidX and Material components so that events arrive as cold Flows or hot ReceiveChannels instead. It is published as a family of per-library modules with a BOM, and the older actor-based overloads remain available for existing integrations.

**LDRAlighieri/Corbind** — ⚡ Kotlin Coroutines binding APIs for Android UI widgets from the platform and support libraries

- Repository: https://github.com/LDRAlighieri/Corbind
- Website: https://ldralighieri.github.io/Corbind
- Stars: 546 · Forks: 22
- Language: Kotlin
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/ldralighieri-corbind

## Two binding styles, and the older one is on its way out

Corbind is a set of Kotlin Coroutines binding APIs for Android UI widgets from the platform, AndroidX and Material libraries, and the README is precise about which style to use.

Use cold Flow bindings for new code; hot ReceiveChannel and actor-based action overloads remain available for existing integrations.

The Description section says the same thing in different words. Corbind turns Android UI callbacks into cold Flow bindings or hot ReceiveChannel bindings. The action overloads use the actor coroutine API, which is marked obsolete upstream.

That distinction matters more than it looks. The actor API was the original shape of Corbind, where a widget callback became a channel you consumed with a for loop. It has since been deprecated in the coroutines library itself, and Corbind has followed by making the Flow bindings the recommended path while keeping the channel and actor overloads for code that has not migrated.

Cold versus hot is the substantive difference for how you use them. A cold Flow restarts its producer for each collector, so two collectors of the same widget event each get their own stream. A hot channel is a single shared producer that broadcasts to whoever is collecting, which is the right shape for an event that only happens once, like a click on a dialog button.

The primary language is Kotlin, the licence is Apache-2.0 with a LICENSE file at the root, the homepage is ldralighieri.github.io/Corbind, and the last push was on 2026-10-20. The release history is steady: 1.13.0 from 2026-09-27, 1.12.1 from 2026-02-13 and 1.12.0 from 2025-09-07. The badges name Kotlin 2.4.20 and Coroutines 1.11.0 as the versions in use, and the minimum API level is 23.

## One module per library, and a BOM to keep them aligned

The Current versions table lists sixteen published artifacts, and the split tells you what the library covers.

There is corbind-bom, which is the platform for the others, and corbind-core. Then there are modules per AndroidX or Material library: corbind-activity, corbind-appcompat, corbind-drawerlayout, corbind-fragment, corbind-leanback, corbind-lifecycle, corbind-material, corbind-navigation, corbind-recyclerview, corbind-slidingpanelayout, corbind-swiperefreshlayout, corbind-viewpager2, and corbind-viewpager which is marked as legacy. There is also a top level corbind module.

So the granularity is by upstream library rather than by widget. You take corbind-activity if you use Activity lifecycle callbacks, corbind-recyclerview for adapter and scroll events, corbind-swiperefreshlayout for the pull to refresh gesture, corbind-viewpager2 for page change events.

The repository layout matches that structure exactly, with one directory per module, each containing its own build files, plus corbind/ and corbind-core/ at the top level.

The dependency declaration uses the BOM, and the platform artifact is declared first.

```kotlin
dependencies { 
    implementation(platform("ru.ldralighieri.corbind:corbind-bom:2026.09.00"))
    implementation("ru.ldralighieri.corbind:corbind")
}
```

The BOM is what makes the module set practical. Sixteen modules published independently would otherwise each need to agree on a common version of corbind-core, and the BOM handles that by fixing the platform version once. The version string here uses a date-based scheme, 2026.09.00, rather than the library's own 1.13.0 release number, so the BOM moves on a different cadence from the modules themselves.

The AndroidX variants follow the same pattern, with the BOM plus one line per library you need.

## Why a widget callback is awkward with coroutines

The two articles linked from the README explain the reasoning, and the first is titled Kotlin Coroutine binding with Flow support.

The problem is structural rather than stylistic. The Android widget APIs are built on listeners. A text field has an addTextChangedListener, a button has an OnClickListener, a RecyclerView has an adapter with several callbacks, and a fragment has a lifecycle with several events. Every one of those callbacks is a void method that arrives on the main thread and carries whatever arguments the framework decided to pass.

In a callback-based codebase, that means the consumer of the event has to be a callback, and anything you want to do with the event beyond handling it immediately, such as transforming it, debouncing it, retrying it, combining it with another stream or surviving a configuration change, has to be built out of listeners and threads.

A Flow binding replaces the listener with a stream, and the surrounding coroutine library then supplies the operators. The transform and filter operators do what a chain of wrapper listeners would do, but they compose, and the collection point becomes an ordinary suspend function.

That is the value Corbind adds, and it is why the project is a set of libraries rather than a single one. Each upstream library has its own listener shapes, and writing a general abstraction over them is not practical, so the coverage is per library and grows as AndroidX adds components.

The limitation follows from the same place. These bindings are for the View based widget system. The Compose world has its own state model, where a click is a state change rather than a callback, and there is no listener for it to bind. The topic tags list the widget names directly, activity, drawerlayout, recyclerview, swiperefreshlayout, viewpager, and appcompat and material, which is a list of View era components. So Corbind and Compose are alternatives rather than companions.

## The project is a Google Design Library and a maintained library, not a weekend project

Several signals in the README indicate the level of attention behind this project.

There is a Google Dev Library badge, which means the project is registered in Google's developer library program for open source Android libraries. There is an API 23+ badge, a publish status badge pointing at a publish.yml workflow, and a Codacy code quality badge. The repository has a CHANGELOG.md, a sample/ directory with its own build files and proguard rules, a build-logic/ directory for shared Gradle convention plugins, and a spotless/ directory, which together with the .editorconfig style of project implies formatting is enforced rather than left to taste.

The sample directory at the repository root tells you the library is exercised by a real application rather than only by unit tests.

The maintenance story is visible in the release cadence. There are three releases across the recent history, 1.12.0 in September 2025, 1.12.1 in February 2026 and 1.13.0 in September 2026, so roughly one release every six or seven months, and a push to the repository on 2026-10-20. That is a slow, steady rhythm for a library that has to track the AndroidX release cycle, since each new AndroidX or Material component is a new binding to write.

The dependency versions are current rather than conservative. Kotlin 2.4.20 and Coroutines 1.11.0 in the badges, and the BOM version 2026.09.00 tracks a September 2026 release. The build uses Kotlin DSL with a build-logic directory, which is the convention for a modern multi-module Android library, and there is a renovate.json at the root for dependency updates.

The project is by LDRAlighieri, and the documentation site is a GitHub Pages site at ldralighieri.github.io/Corbind, with the wiki-style articles linked from the README.

## Where Corbind is the wrong tool

The first wrong-tool case is a Compose codebase. Corbind binds the listener APIs of the View system, and a Compose application has no listeners to bind for most interactions, since state and event handlers replace them. The topic tags are a list of View era components, so if your UI is Compose, most of this library does not apply to you.

The second case is a codebase that has not adopted coroutines. The whole library exists to expose callbacks as coroutine primitives, and if your project is still on callbacks and listeners throughout, adding Corbind for one widget is more machinery than the problem needs.

The third case is a team that needs the newest widget immediately. Because the coverage is per upstream library and is written by hand, a component that shipped in the latest AndroidX release is not bound until someone writes it. That is inherent to the approach and it is a fair trade for the type safety, but it means Corbind lags the platform by however long it takes to catch up.

The fourth case is a very small project. If you have one activity and one button, the binding is a one-line listener and a coroutine scope, and a library with sixteen modules and a BOM is more configuration than the feature.

There is also a deprecation burden to think about. The action overloads are built on the actor coroutine API, which upstream has marked obsolete, and Corbind keeps them for existing integrations. So a codebase that adopted the channel-based overloads early has a migration ahead of it, and the README is explicit that new code should use the Flow bindings instead. That is the right call on the library's part, but it does mean you should check which overloads your own code is using before you upgrade.

On the API level, the minimum is 23, which is Android 6.0, so the library does not run on the older devices some projects still support.

On licence, Apache-2.0 with a LICENSE file at the root, which is the grant most widely used for Android libraries and imposes no copyleft obligation on the app that consumes it. The dependency is the practical consideration rather than the licence: the library brings in the coroutines API and whichever AndroidX or Material modules your app already uses, so it adds nothing to your dependency graph that you do not already have.

## Conclusion

Corbind suits an Android team that has moved its UI layer to coroutines and wants widget events to compose with the same Flow operators as everything else, since the modules are published per library and pulled in through a BOM. It does not suit a codebase that has not adopted coroutines, and it does not cover the newer Compose APIs, since the bindings are for the View based widgets. Before adopting, note that the project is still carrying the older action overloads on an API the coroutine library has marked obsolete upstream, so new code should use the Flow bindings and the legacy path exists only for compatibility.

## FAQ

### What is Corbind?

Corbind is a set of Kotlin libraries providing coroutine binding APIs for Android UI widgets from the platform, AndroidX and Material libraries. It turns widget callbacks into cold Flow bindings or hot ReceiveChannel bindings, with the older actor-based action overloads kept for existing integrations.

### How do I add Corbind to an Android project?

Declare the BOM as a platform dependency and then the modules you need, for example implementation(platform("ru.ldralighieri.corbind:corbind-bom:2026.09.00")) followed by implementation("ru.ldralighieri.corbind:corbind"). There is a separate module per upstream library, such as corbind-activity, corbind-recyclerview and corbind-viewpager2.

### Should I use the Flow bindings or the action overloads in Corbind?

The README says to use cold Flow bindings for new code and that the hot ReceiveChannel and actor-based action overloads remain available for existing integrations. The action overloads use the actor coroutine API, which is marked obsolete upstream.

### Which Android components does Corbind cover?

The published modules cover Activity, AppCompat, DrawerLayout, Fragment, Leanback, Lifecycle, Material, Navigation, RecyclerView, SlidingPaneLayout, SwipeRefreshLayout, ViewPager2 and the legacy ViewPager, alongside corbind-core and the corbind-bom.

### Does Corbind work with Jetpack Compose?

The bindings are for the View based Android widgets from the platform, AndroidX and Material libraries, so they cover the listener based component set rather than the Compose state model. The topic tags list the View era widget names directly.

### What license is Corbind released under?

Corbind is licensed under the Apache License 2.0, with the LICENSE file at the root of the repository. The current release is 1.13.0, tagged on 2026-09-27, and the library targets Kotlin 2.4.20 with Coroutines 1.11.0 and a minimum API level of 23.

## Sources

- [LDRAlighieri/Corbind on GitHub](https://github.com/LDRAlighieri/Corbind)
- [License: Apache-2.0](https://github.com/LDRAlighieri/Corbind/blob/master/LICENSE)
- [Project website](https://ldralighieri.github.io/Corbind)
- [README](https://github.com/LDRAlighieri/Corbind/blob/master/README.md)
- [Releases](https://github.com/LDRAlighieri/Corbind/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ldralighieri-corbind
