A graceful multiplatform bluesky client
Heron is a Jetpack Compose adaptive, reactive and offline-first bluesky client.
![]() | ![]() |
---|
Heron uses Material design and motion and is heavily inspired by the Crane material study.
Libraries:
This is a multi-module Kotlin Multiplatform project targeting Android, iOS and Desktop that follows the Android architecture guide.
For more details about this kind of architecture, take a look at the Now in Android sample repository, this app follows the same architecture principles it does, and the architecture decisions are very similar.
There are 6 kinds of modules:
data-*
is the data layer of the
app containing models data and repository implementations for reading and writing that data.
Data reads should never error, while writes are queued with a WriteQueue
.
MultipleEntitySaver
is used to save bluesky
network models.domain-*
is the domain layer
where aggregated business logic lives. This is mostly domain-timeline
where higher level
abstractions timeline data manipulation exists.feature-*
contains navigation destinations or screens in the app. Multiple features can
run side by side in app panes depending on the navigation configuration and device screen size.ui-*
contains standalone and reusable UI components and Jetpack Compose effects for the app
ranging from basic layout to multimedia components for displaying photos and video playback.scaffold
contains the application state in the AppState
class, and coordinates app level
UI logic like pane display, drag to dismiss, back previews and so on. It is the entry point to
the multiplatform application/composeApp
is app module that is the fully assembled app and depends on all other modules.
It offers the entry point to the application for a platform.
It contains several subfolders:
commonMain
is for code that’s common for all targets./iosApp
is the entry point for the iOS app.Dependency injection is implemented with the Kotlin Inject library which constructs the dependency graph at build time and therefore is compile time safe. Assisted injection is used for feature screens to pass navigation arguments information to the feature.
Navigation uses the treenav experiment to implement
Android adaptive navigation.
Specifically it uses a ThreePane
configuration, where up to 3 navigation panes may be shown, with
one reserved for back previews and another for modals. Navigation state is also saved to disk and
persisted across app restarts.
CoroutineScope
for each ViewModel
is obtained from the composition's LocalLifecycleOwner
inputs
argument, or derived from an action in actionTransform
.SharingStarted.WhileSubscribed(FeatureWhileSubscribed)
.Action
is in a sealed hierarchy, and action parallelism is defined by the Action.key
. Actions with different keys run in parallel
while those in the same key are processed sequentially. Each distinct subtype of an Action
hierarchy typically has it's own
key unless sequential processing is required for example:
Action.Navigation
typically share the same key.Kotlin multiplatform Bluesky/ATProtocol library.
Kotlin Multiplatform bindings for Bluesky
Telnet client for Bluesky + AT Protocol
Mastdon\Bluesky\RSS client, implementation based on Kotlin Multiplatform and Compose Multiplatform.
An experimental ATP/Bluesky client app for Android
Your Brand Here!
50K+ engaged viewers every month
Limited spots available!
📧 Contact us via email🦋 Contact us on Bluesky