Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

109 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WARP Logo

WARP

Widget Abstraction & Rendering Pipeline for Kotlin Multiplatform.
Write home screen widgets once in Kotlin — render natively on Android (Glance) and iOS (WidgetKit + SwiftUI).

Kotlin 2.4.0 Java 17 iOS 17+ Android 7+ MIT License Maven Central Version Repository Views

Read Documentation Buy Me A Coffee


Overview

showcase.mp4

⚠️ Alpha Stage: WARP is currently in Alpha. APIs and implementation details may evolve based on community feedback. If you discover any bugs or have feature requests, please open an issue on GitHub Issues.

WARP is a declarative widget engine for Kotlin Multiplatform developers.

It allows you to describe home screen widget UI using familiar Compose syntax (WarpColumn, WarpRow, WarpText, WarpButton), serialize the resulting Abstract Syntax Tree (AST) to JSON, and render it using 100% native platform frameworks on each OS:

  • Android: Compiles to Jetpack Glance RemoteViews.
  • iOS: Compiles to SwiftUI WidgetKit extensions with interactive AppIntents.
Declarative Compose Kotlin UI  ──>  WarpNode AST  ──>  JSON  ──>  Native Platform Renderers
                                          │
                             Shared State & Action Handlers

Key Features

  • 100% Shared UI Code: Write layout logic, state models, and click actions once in commonMain.
  • 🎨 True Native Views: No canvas painting or heavy Skia runtime. Renders native platform views on both Android and iOS.
  • 🪶 Zero App Size Inflation: Only depends on compose.runtime — does not pull in compose.ui graphics pipelines.
  • 🔄 Automatic State Store: Persistent widget state saved across system restarts using SharedPreferences (Android) and UserDefaults App Groups (iOS).
  • 📐 Adaptive Size Bucketing: Automatically scales UI across Small, Medium, and Large widget sizes.
  • 🧙 Interactive Swift Wizard: Generate iOS WidgetKit SwiftUI and AppIntent boilerplate instantly via warp.atherio.dev/wizard.html.

Getting Started

1. Version Catalog (libs.versions.toml)

Add WARP and serialization dependencies to your catalog:

Maven Central Version

[versions]
warp = "0.1.4"
kotlinx-serialization-json = "1.11.0"
compose-multiplatform = "1.11.1"

[libraries]
warp-widget = { group = "io.github.devatrii", name = "warp-widget", version.ref = "warp" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }
compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose-multiplatform" }

[plugins]
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

2. Shared Gradle Configuration (build.gradle.kts)

In your shared KMP module build.gradle.kts:

plugins {
    alias(libs.plugins.kotlin.serialization)
    alias(libs.plugins.composeCompiler)
}

kotlin {
    listOf(iosArm64(), iosSimulatorArm64()).forEach { iosTarget ->
        iosTarget.binaries.framework {
            export(libs.warp.widget)
        }
    }

    sourceSets {
        commonMain.dependencies {
            api(libs.warp.widget)
            implementation(libs.kotlinx.serialization.json)
            implementation(libs.compose.runtime)
        }
    }
}

Creating Your First Widget

/** 1. State */
@Serializable
data class CounterState(val count: Int = 0)

/** 2. Type-Safe Actions */
@Serializable
sealed class CounterActions {
    @Serializable data object Increment : CounterActions()
    @Serializable data object Decrement : CounterActions()
}

/** 3. Widget Definition */
object CounterWarpWidget : WarpWidget<CounterState>(CounterState.serializer()) {
    override val id: String = "CounterWidget"
    override val iosGroupId: String = "group.com.example.app"
    override val stateScope: WarpWidgetStateScope = WarpWidgetStateScope.Shared

    override suspend fun defaultState(): CounterState = CounterState()

    @Composable
    override fun Content(env: WidgetEnvironment, state: CounterState) {
        WarpTheme(environment = env) {
            WarpRow(
                modifier = WarpModifier.fillMaxWidth().padding(16.dp),
                verticalAlignment = WarpVerticalAlignment.Center
            ) {
                WarpButton("", CounterActions.Decrement.asClickAction())
                WarpText("${state.count}", modifier = WarpModifier.weight())
                WarpButton("+", CounterActions.Increment.asClickAction())
            }
        }
    }

    override fun clickHandlers(session: WarpWidgetSession): List<WarpActionHandler<*>> =
        listOf(CounterActionHandler(session))
}

iOS Build Size & Benchmark Report

Below is the real-world iOS build size report for the Todo Widget Example App:

Artifact Component / Path Release Size Note
Xcode App Store Archive (.ipa) TodoWidget.ipa (App Thinning Export) 1.8 MB Official App Store Download Size
Installed App Size (Thinned) On-Device Installed Footprint 5.8 MB Official App Store Install Size
Shared KMP Framework SharedLogic.framework 18.0 MB ~73% Release Binary Stripping
Widget Extension Bundle TodoWidgetExtension.appex 8.50 MB Uncompressed bundle on-disk

Module Overview

Module Role
warp-runtime Compose compiler DSL, WarpNode AST tree, WarpModifier chain, serializable actions
warp-ui Native platform renderers — Jetpack Glance (Android) & SwiftUI generator (iOS)
warp-widget Shared WarpWidget API, session manager, persistent state store, WarpTheme, WarpAdaptive
warpWidgetKit SPM SwiftUI / WidgetKit package (import warpWidgetKit) for Xcode extensions
shared Shared KMP module with Counter widget demo
examples/todo-widget Complete full-featured Todo Widget example application

Documentation & Resources


License & Usage

WARP is open-source software released under the MIT License. You are free to use, modify, and distribute it in personal or commercial applications.

Read Documentation Buy Me A Coffee

About

WARP — Widget Abstraction & Rendering Pipeline for KMP. Write widget UI once in Kotlin; render on Android (Glance) and iOS (WidgetKit)

Resources

Contributing

Stars

26 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages