Skip to content

What is PulsePlatform? ​

PulsePlatform is a framework for building desktop and mobile apps with AI agents. Its aim is to have an agent write the right code, so that an idea takes shape as an app and keeps its shape as the app grows. It has two parts: rules, which are tests your project runs, and a library, which holds the pieces those rules expect. It is built on Compose Multiplatform, with desktop apps on the JVM and Android and iOS apps sharing their Kotlin.

From an idea to an app ​

You describe what the app should do. The agent writes it with the library's pieces, runs the one test that holds the rules, and fixes what the failures name, until the test passes. You review an app whose code already has the agreed shape, and the next idea is built on the same shape, whoever writes it. Building with AI agents sets this loop up.

Why rules first ​

An AI agent writes a screen that compiles and works on the first try. What it does not keep by itself is the shape of the code around it. One screen binds its ViewModel in a section, another keeps a var beside its state, a third puts a label in the domain. Each choice works on its own, and the codebase drifts.

A rule written in a prompt or a style guide is easy to skip. A rule that is a failing test is not. PulsePlatform's rules are Konsist assertions you call from one test in your own suite. When the code drifts, the test fails, names the file, and says what to move where. An agent reads that message and fixes the code the same way it fixes a compile error.

The library is the other half. The rules ask that one place binds each ViewModel, that sections and components take only data and callbacks, and that state is one immutable value. The library makes that the easy way to write a screen, so following the rules does not mean writing more code.

What the rules cover ​

AreaWhat is checked
UI structurehow a feature is split into the place that binds the ViewModel, sections and components; states and messages; previews
Domain and datahow a repository hands out data, and when a use case is worth writing
Modules and Koinwhich module may depend on which, the packages inside them, and where Koin modules are declared
Textthat every string a user reads comes from string resources, so the app can be translated

Desktop and mobile ​

A desktop app and a mobile app built with PulsePlatform are two products, each shaped for how it is used, and they share their domain and data rather than their screens; an app on both keeps them under desktop/ and mobile/, as Desktop and mobile describes. The rules and the core are the same on every platform: PulseViewModel holds one immutable state, handles actions and emits events, and PulseContent binds it to the UI. What differs is how many ViewModels a screen has.

A desktop window shows a sidebar, an editor and an inspector at once. Each is a content with its own ViewModel, a host lays them out, and a Container above them carries messages between them. A phone shows one screen at a time, so a screen has one ViewModel and binds it itself, with no Container.

DesktopMobile
Artifactmvi-desktopmvi-mobile
TargetsJVM (Compose Desktop)Android, iOS (Compose Multiplatform)
A feature isa host, its contents, and a Containerone screen and one ViewModel
Binds a ViewModeleach contentthe screen
Messages between ViewModelsBroadcast and Unicast through the Containernone
RulesassertPulseMviConventions()assertPulseMobileConventions()
Desktop                                  Mobile
counter/                                 counter/
├── CounterHost.kt                       ├── CounterScreen.kt
├── CounterContainer.kt                  ├── CounterViewModel.kt
├── CounterContracts.kt                  ├── CounterContracts.kt
├── content/                             ├── section/
│   └── total/                           └── component/
│       ├── TotalContent.kt
│       ├── TotalViewModel.kt
│       ├── TotalContracts.kt
│       └── section/
├── section/
└── component/

Artifacts ​

PulsePlatform is published on JitPack as five artifacts. Use the rules on every platform, and the MVI and Navigation 3 artifacts for your target.

ArtifactRolePlatforms
architecturethe rules, as Konsist assertions for your testsruns on the JVM; checks desktop and mobile code
mvi-desktopPulseViewModel, PulseContainer, PulseHost, PulseContent and the five marker interfacesdesktop
mvi-mobilePulseViewModel, PulseContent and three marker interfacesAndroid, iOS
navigation-desktopties ViewModels and Containers to a Navigation 3 back stack entrydesktop
navigation-mobileties ViewModels to a Navigation 3 back stack entryAndroid, iOS

Installation ​

Add JitPack to settings.gradle.kts, then the artifacts for your platform to build.gradle.kts. Replace <version> with a tag from GitHub Releases.

kotlin
// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        maven { url = uri("https://jitpack.io") }
    }
}
kotlin
// build.gradle.kts — desktop
dependencies {
    implementation("com.github.kaleidot725.PulsePlatform:mvi-desktop:<version>")
    implementation("com.github.kaleidot725.PulsePlatform:navigation-desktop:<version>")
    testImplementation("com.github.kaleidot725.PulsePlatform:architecture:<version>")
}
kotlin
// build.gradle.kts — mobile (Compose Multiplatform)
kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("com.github.kaleidot725.PulsePlatform:mvi-mobile:<version>")
            implementation("com.github.kaleidot725.PulsePlatform:navigation-mobile:<version>")
        }
    }
}

dependencies {
    // the rules run in the Android unit tests
    testImplementation("com.github.kaleidot725.PulsePlatform:architecture:<version>")
}

Requirements ​

RequirementVersion
Java17+
Kotlin2.0+
Compose Multiplatform1.6+
AndroidminSdk 26

Next steps ​

Released under the Apache 2.0 License.