| title | Quickstart |
|---|---|
| description | Build and run your first Klyx extension |
This guide walks you through creating a minimal Klyx extension from scratch. You'll set up a project, implement the plugin interface, and bundle it into a .klyx file.
- A Klyx-compatible device or emulator running Klyx 4.2.0+
- Basic knowledge of Kotlin and Jetpack Compose
Create a new Android project in Android Studio with No Activity. Use minimum SDK 28 and Kotlin.
Your project structure should look like this:
my-extension/
├── app/
│ ├── build.gradle.kts
│ └── src/main/
│ ├── AndroidManifest.xml
│ └── java/com/myextension/
│ └── MyPlugin.kt
├── build.gradle.kts
├── settings.gradle.kts
├── gradle.properties
├── gradle/
│ └── libs.versions.toml
└── plugin.json
In gradle/libs.versions.toml:
[versions]
# agp and kotlin version must match with klyx app's agp and kotlin version
agp = "9.2.1"
kotlin = "2.4.0"
klyx = "4.2.0-SNAPSHOT"
[libraries]
klyx-api = { module = "io.github.klyx-dev:klyx-api", version.ref = "klyx" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
klyx = { id = "io.github.klyx-dev.plugin", version.ref = "klyx" }In build.gradle.kts:
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.kotlin.compose) apply false
alias(libs.plugins.klyx) apply false
}In app/build.gradle.kts:
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.klyx)
}
klyx {
enableCompose()
outputDirectory = rootProject.file("output")
}
android {
namespace = "com.myextension"
}
dependencies {
compileOnly(libs.klyx.api)
}In app/src/main/AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application tools:ignore="MissingApplicationIcon" />
</manifest>In plugin.json (at the project root):
{
"id": "com.myextension.helloworld",
"name": "Hello World",
"version": "1.0.0",
"minAppVersion": "4.2.0",
"entryClass": "com.myextension.MyPlugin",
"description": "My first Klyx extension",
"author": {
"name": "Your Name"
},
"license": "MIT",
"permissions": []
}In app/src/main/java/com/myextension/MyPlugin.kt:
package com.myextension
import androidx.compose.material3.Text
import com.klyx.api.plugin.KlyxPlugin
import com.klyx.api.plugin.PluginInfo
import com.klyx.api.plugin.runtime
import com.klyx.api.ui.Screen
import com.klyx.api.ui.ScreenId
import com.klyx.api.ui.ScreenRegistry
import com.klyx.api.service.plugin
class MyPlugin : KlyxPlugin {
private val screens: ScreenRegistry by plugin()
private val info: PluginInfo by runtime()
override suspend fun onLoad() {
screens.register(
this,
Screen(ScreenId("hello.main")) {
Text("Hello from ${info.descriptor.name}!")
}
)
}
override suspend fun onStart() {}
override suspend fun onStop() {}
override suspend fun onUnload() {
screens.unregister(ScreenId("hello.main"))
}
}Run the Gradle task:
./gradlew klyxBundleDebugThis produces output/my-extension.klyx — a bundle containing your APK, plugin.json, and any assets.
Transfer the .klyx file to your device and open it with Klyx. Klyx detects the bundle, reads plugin.json, loads the APK, instantiates your entryClass, and calls onLoad() followed by onStart().
Navigate to your screen from within Klyx's navigation.
Full reference for plugin.json fields Understand load, start, stop, and unload