> ## Documentation Index
> Fetch the complete documentation index at: https://klyx.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Building & Bundling

> How to build, bundle, and distribute Klyx extensions

Klyx extensions are built using the Klyx Gradle plugin, which packages your APK and generated manifest into a `.klyx` bundle (a gzipped tarball).

## The Klyx Gradle plugin

Apply the plugin in your `app/build.gradle.kts`:

```kotlin theme={null}
plugins {
    alias(libs.plugins.klyx)
}

android {
    namespace = "com.yourext"
    compileSdk = 37
}

klyx {
    outputDirectory.set(rootProject.file("output"))
}
```

The Klyx Gradle plugin (`io.github.klyx-dev.compiler.plugin`) does several things:

* Applies the Kotlin compiler plugin that processes `@PluginManifest`
* Auto-detects `icon.png`, `readme.md`, and `changelog.md` from the project root
* Applies the Android Application or Library plugin automatically
* Enables Jetpack Compose if the `compose` option is set (enabled by default)
* Adds `klyx-api` as a `compileOnly` dependency automatically
* Sets `minSdk` to 28, Java 21 compatibility, and `buildFeatures.compose = true`

You do not need to apply `com.android.application`, `kotlin.compose`, or `kotlin.serialization` yourself — the klyx plugin handles all of that.

## Configuration options

All options are available on the `klyx { }` extension block:

| Option             | Type                         | Default                            | Description                                             |
| ------------------ | ---------------------------- | ---------------------------------- | ------------------------------------------------------- |
| `pluginJsonFile`   | `RegularFileProperty`        | `build/klyx/generated/plugin.json` | Path to the generated descriptor JSON                   |
| `icon`             | `RegularFileProperty`        | Auto-detected                      | Plugin icon file                                        |
| `readme`           | `RegularFileProperty`        | Auto-detected                      | Readme displayed on the plugin details page             |
| `changelog`        | `RegularFileProperty`        | Auto-detected                      | Version history                                         |
| `extraFiles`       | `ConfigurableFileCollection` | Empty                              | Additional files to pack into the bundle                |
| `outputFileName`   | `Property<String>`           | Project name                       | Name of the output bundle (without extension)           |
| `outputDirectory`  | `DirectoryProperty`          | `build/klyx`                       | Where to output the `.klyx` bundle                      |
| `autoPushToDevice` | `Property<Boolean>`          | `false`                            | Whether to auto-push to a connected device via adb      |
| `library`          | `Property<Boolean>`          | `false`                            | Whether to build as a library instead of an application |
| `compose`          | `Property<Boolean>`          | `true`                             | Whether to enable Jetpack Compose                       |

### Auto-detected files

The plugin automatically detects and includes these files from the project root if you do not specify them explicitly:

| File                    | Purpose                                                          |
| ----------------------- | ---------------------------------------------------------------- |
| `plugin.json`           | Generated by the compiler plugin (required — do not hand-author) |
| `icon.png` / `icon.jpg` | Plugin icon shown in the plugin manager                          |
| `readme.md`             | Displayed on the plugin details page                             |
| `changelog.md`          | Version history                                                  |

## Build tasks

The plugin adds several Gradle tasks:

| Task                | Description                                              |
| ------------------- | -------------------------------------------------------- |
| `klyxBundleDebug`   | Build a debug `.klyx` bundle                             |
| `klyxBundleRelease` | Build a release `.klyx` bundle                           |
| `klyxBundle`        | Build the release bundle (alias for `klyxBundleRelease`) |
| `klyxPushDebug`     | Push the debug bundle to a connected device              |
| `klyxPushRelease`   | Push the release bundle to a connected device            |

The push tasks run automatically after bundling when `autoPushToDevice` is `true`:

```bash theme={null}
./gradlew klyxBundleDebug
```

This produces `output/MyExtension.klyx`.

## Bundle format

The task produces a `.klyx` file — a gzipped tarball containing:

```
MyExtension.klyx
├── plugin.apk       -- Compiled extension (debug or release APK)
├── plugin.json      -- Generated plugin descriptor
├── icon.png         -- Plugin icon (if present)
├── readme.md        -- Documentation (if present)
├── changelog.md     -- Version history (if present)
└── [extra files]    -- Anything configured via extraFiles
```

| Entry          | Required | Description                                        |
| -------------- | -------- | -------------------------------------------------- |
| `plugin.json`  | Yes      | Generated by the `@PluginManifest` compiler plugin |
| `plugin.apk`   | Yes      | The compiled APK                                   |
| `icon.png`     | No       | Store icon (512x512 recommended)                   |
| `readme.md`    | No       | Plugin description and docs                        |
| `changelog.md` | No       | Version changelog                                  |

## Android Studio IDE support

For the best plugin development experience, enable the klyx compiler plugin in Android Studio so you get IDE features like code completion and navigation for Klyx APIs.

Go to **Menu > Help > Edit Custom Properties...** and add this line to the `idea.properties` file:

```properties theme={null}
kotlin.k2.only.bundled.compiler.plugins.enabled=false
```

Restart Android Studio after making this change.

## R8 / ProGuard

If you enable minification, keep your entry class:

```pro theme={null}
-keep class com.myext.MyExtension { *; }
```

The `@PluginManifest` annotation ensures the entry class name is generated into `plugin.json`. However, if R8 renames or removes the class, Klyx will not be able to load it reflectively. Make sure to add a keep rule.

## AndroidManifest

Keep it minimal:

```xml theme={null}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <application tools:ignore="MissingApplicationIcon" />
</manifest>
```

No activities, services, or providers are needed. The plugin entry point is declared via the `@PluginManifest` annotation, not the manifest.

## Version compatibility

The `minAppVersion` in your `@PluginManifest` annotation should match the version of `klyx-api` you are compiling against. For example, if your `build.gradle.kts` uses a version catalog:

```toml theme={null}
[versions]
klyx = "4.2.0-SNAPSHOT"
```

then set `minAppVersion = "4.2.0"` in the `@PluginManifest`.

## Publishing to the registry

Klyx hosts a community plugin registry at [github.com/klyx-dev/plugins](https://github.com/klyx-dev/plugins). Publishing is done through a pull request — CI validates your bundle and publishes it automatically on merge.

### Prerequisites

1. Your `@PluginManifest` annotation is valid (see [manifest reference](/extensions/manifest) for validation rules)
2. You have built a `.klyx` bundle with `./gradlew klyxBundle`

### Publish via pull request

1. **Fork** the [registry repo](https://github.com/klyx-dev/plugins/fork)
2. **Add** your `.klyx` file to the `incoming/` directory
3. **Create a pull request** to `main`
4. **Wait for CI** — the workflow validates your bundle and posts results as a PR comment
5. **Merge** once validation passes — your plugin is published automatically

### What CI validates

The registry CI pipeline checks:

* `plugin.json` exists and is valid JSON
* All required fields are present and non-empty: `id`, `version`, `name`, `minAppVersion`, `entryClass`
* `id` matches the format: reverse-DNS (e.g. `com.example.myplugin`)
* `version` follows semver (e.g. `1.0.0`)
* `minAppVersion` and `maxAppVersion` follow semver
* `entryClass` is a valid fully-qualified class name
* `author.name` is present if `author` is an object
* `plugin.apk` exists in the bundle

### After publishing

The `publish` workflow:

1. Creates a directory under `plugins/{plugin-id}/` with all versioned bundles and extracted metadata
2. Updates `plugins/index.json` — the auto-generated registry index
3. Purges the jsDelivr CDN cache so users see the latest version
4. Clears the `incoming/` directory

### Ownership

When you first publish a plugin, you become its owner. The registry tracks ownership through a Cloudflare Worker at `plugins.klyx.workers.dev`. Only the registered owner can publish updates to that plugin ID. This prevents namespace squatting and unauthorized updates.

### Manual distribution

You can also share `.klyx` files directly with users. They can open the file with Klyx to install the extension.
