Write real Jetpack Compose. Push updates to every device in seconds.
@KetoyEntryPoint @Composable
fun CheckoutScreen() {
val vm = ketoyViewModel<CheckoutViewModel>()
val state by vm.state.collectAsState()
Scaffold(topBar = { TopAppBar(title = { Text("Checkout") }) }) { p ->
LazyColumn(modifier = Modifier.padding(p)) {
items(state.cartItems) { item ->
ProductCard(name = item.name, price = item.price)
}
}
Button(onClick = { vm.dispatch("place_order") }) {
Text("Place Order - $" + state.total)
}
}
}
// $ ./gradlew ketoyBundle → checkout.ktx · 3.4 KBAdd one annotation. Run one Gradle task. Every device gets the change in seconds.
Ketoy generates code on device, the same way ART does. It stays inside Google policy.
Security modelKetoy supports the full Compose toolkit, not a curated subset. When Compose adds a parameter, one command picks it up.
All 35 Material 3 components. Every parameter included.
Data classes, sealed classes, extensions, and lambdas. Real Kotlin, compiled to bytecode.
launch, async, withContext, and 9 Flow operators. Structured concurrency included.
A real Android ViewModel. It survives config changes and works with Hilt.
HTTP, DataStore, Room, and navigation. 67 capabilities built in.
Drop it in. @Inject works exactly as before.
One annotation and one Gradle task. That is the whole difference.
See everything Ketoy supportsKetoy verifies every bundle before it runs. Here is how, in three parts.
An Ed25519 signature is checked before any code runs. Your private key stays on your server. Only you can ship a bundle.
The compiler rejects file access, reflection, and any unregistered API. Unsafe code never compiles.
KBC code reaches the platform through registered capabilities. Nothing else is callable.
Yes. Ketoy generates code on device, exactly like ART does with bytecode. It is the same idea as Lua in a game engine. If your CDN goes down, the last signed bundle keeps running.
Add the plugin. Write your Compose screen. Run ketoyBundle and upload.
plugins {
id("dev.ketoy.compiler") version "0.4.13-alpha"
}
dependencies {
implementation(platform("dev.ketoy.vm:ketoy-bom:0.4.13-alpha"))
implementation("dev.ketoy.vm:ketoy-runtime")
implementation("dev.ketoy.vm:ketoy-hilt")
implementation("dev.ketoy.vm:ketoy-adapters-material3")
ksp("dev.ketoy.vm:ketoy-ksp-processor")
}// The same Compose you already write.
@KetoyEntryPoint
@Composable
fun HomeScreen() {
val vm = ketoyViewModel<HomeViewModel>()
val state by vm.state.collectAsState()
Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
Text("Welcome, " + state["name"])
Button(onClick = { vm.dispatch("get_started") }) {
Text("Get Started")
}
}
}# Compile to KBC
$ ./gradlew :ketoy-screens:ketoyBundle
> Task :ketoy-screens:ketoyBundle
HomeScreen.kt → home.ktx 2.1 KB
CheckoutScreen.kt → checkout.ktx 3.4 KB
Signed: Ed25519
Compressed:Brotli q=11
# Upload. That's the whole release process.
$ aws s3 cp build/ketoy-bundles/ s3://cdn/ketoy/ \
--recursive --content-encoding br
# Live on every device in ~60s.Stuck on something, evaluating Ketoy for your team, or wondering if your weird in-house SDK is supported? We answer every email. Usually within the same day. Sometimes faster than your Play Store review.
Drop us a note. Real engineers read these - no Tier-1 ticket triage, no chatbots. (We have an AI that ships code. Not one that answers email.)