
Authoring toolkit and package format for standalone .suvio plugins, building single-component WASM packages, typed contribution APIs (catalog, playback, settings) and preview surfaces with optional DI.
Suvio Plugin SDK V8 is the Kotlin authoring toolkit and package format for
standalone .suvio plugins.
1.0.0-rc.22 uses Kotlin 2.4.20-Beta2. It is an EAP release candidate;
stable 1.0.0 will be rebuilt and released only after Kotlin 2.4.20 is
final and the stability gates have passed.
Requirements and exact versions are generated in the compatibility matrix. Plugin builds currently require JDK 25.
Add Maven Central to plugin and dependency resolution. The optional local repository property is used by SDK conformance builds and can be omitted by regular plugin projects:
// settings.gradle.kts
pluginManagement {
val localSdkRepository = providers.gradleProperty("suvio.pluginSdkMaven").orNull
val sdkVersion = providers.gradleProperty("suvio.sdkVersion").orElse("1.0.0-rc.22")
repositories {
localSdkRepository?.let { repository ->
maven { url = uri(repository) }
}
mavenCentral()
gradlePluginPortal()
}
plugins {
id("uk.shusek.suvio.plugin") version sdkVersion.get()
}
}
dependencyResolutionManagement {
val localSdkRepository = providers.gradleProperty("suvio.pluginSdkMaven").orNull
repositories {
localSdkRepository?.let { repository ->
maven { url = uri(repository) }
}
google()
mavenCentral()
}
}
rootProject.name = "example-suvio-plugin"Apply only the Suvio plugin. It applies Kotlin Multiplatform, serialization, KRWA, the WASI target, and exactly matching SDK dependencies:
// build.gradle.kts
plugins {
id("uk.shusek.suvio.plugin")
}
suvioPlugin {
namespace = "org.example.catalog"
version = "1.0.0"
author("Example")
metadata {
name = stringResource("plugin_name")
description = stringResource("plugin_description")
}
icon {
foreground = file(
"src/commonMain/composeResources/drawable/plugin_icon_foreground.png",
)
backgroundColor = "#101828"
}
surfaces {
catalog()
}
}Create a typed contribution in commonMain:
package org.example.catalog
import uk.shusek.suvio.extensions.sdk.*
@CatalogContribution
class ExamplePlugin : CatalogPlugin {
override suspend fun catalogs(): List<SuvioCatalogDescriptor> = TODO()
override suspend fun catalogPage(
catalogId: String,
mediaType: SuvioMediaType?,
pageToken: String?,
limit: Int,
searchTerm: String?,
filters: List<SuvioCatalogFilterSelection>,
sortId: String?,
sortDirection: SuvioCatalogSortDirection?,
): SuvioCatalogPageResponse = TODO()
override suspend fun mediaDetails(locator: MediaLocator): SuvioMediaDetails? = TODO()
}Put the selected metadata strings in
src/commonMain/composeResources/values/strings.xml and translations in
values-<locale>/strings.xml.
<resources>
<string name="plugin_name">Example Catalog</string>
<string name="plugin_description">Example media catalog.</string>
</resources>Build and execute tests with:
./gradlew suvioWasmWasmtimeTest packageSuvioPluginThe package contains exactly one executable:
components/plugin.wasm
All declared stable and preview surfaces are exports of that same Component Model component. Declaring more surfaces never creates additional Wasm files.
Stable for the 1.x line:
@CatalogContribution, CatalogPlugin, optional CatalogFacetsPlugin, and
CatalogEpisodesPlugin;@PlaybackContribution, PlaybackPlugin, and its optional interfaces;@SettingsContribution and hosted Settings UI.There is no root plugin class. Each annotated contribution is created only when one of its operations is dispatched. Metro constructor injection is an optional author choice; when Metro is applied, the SDK generates the invocation-scoped graph.
Preview surfaces require both surfaces.preview { ... } in Gradle and
@OptIn(ExperimentalSuvioPluginApi::class) in Kotlin:
Jellyfin is the stable reference plugin. MDBList is the preview reference
plugin. The executable all-surfaces example used by the release gate lives in
integration-tests/component-host-plugin.
The SDK is published under these module names:
plugin-apiplugin-runtime-wasiplugin-uiplugin-formatplugin-host-apiplugin-wituk.shusek.suvio.plugin.gradle.pluginPlugin authors do not add those dependencies manually. A manually versioned authoring dependency fails configuration with a readable error.
Generated Dokka HTML and a real Dokka JAR are produced by the documentation and publication tasks.
The SDK is source-available under the Suvio Plugin SDK License 1.0. Plugin authors retain ownership of their original code. GPLv3 plugins must include the Suvio SDK Linking Exception 1.0; see the license FAQ.
Suvio Plugin SDK V8 is the Kotlin authoring toolkit and package format for
standalone .suvio plugins.
1.0.0-rc.22 uses Kotlin 2.4.20-Beta2. It is an EAP release candidate;
stable 1.0.0 will be rebuilt and released only after Kotlin 2.4.20 is
final and the stability gates have passed.
Requirements and exact versions are generated in the compatibility matrix. Plugin builds currently require JDK 25.
Add Maven Central to plugin and dependency resolution. The optional local repository property is used by SDK conformance builds and can be omitted by regular plugin projects:
// settings.gradle.kts
pluginManagement {
val localSdkRepository = providers.gradleProperty("suvio.pluginSdkMaven").orNull
val sdkVersion = providers.gradleProperty("suvio.sdkVersion").orElse("1.0.0-rc.22")
repositories {
localSdkRepository?.let { repository ->
maven { url = uri(repository) }
}
mavenCentral()
gradlePluginPortal()
}
plugins {
id("uk.shusek.suvio.plugin") version sdkVersion.get()
}
}
dependencyResolutionManagement {
val localSdkRepository = providers.gradleProperty("suvio.pluginSdkMaven").orNull
repositories {
localSdkRepository?.let { repository ->
maven { url = uri(repository) }
}
google()
mavenCentral()
}
}
rootProject.name = "example-suvio-plugin"Apply only the Suvio plugin. It applies Kotlin Multiplatform, serialization, KRWA, the WASI target, and exactly matching SDK dependencies:
// build.gradle.kts
plugins {
id("uk.shusek.suvio.plugin")
}
suvioPlugin {
namespace = "org.example.catalog"
version = "1.0.0"
author("Example")
metadata {
name = stringResource("plugin_name")
description = stringResource("plugin_description")
}
icon {
foreground = file(
"src/commonMain/composeResources/drawable/plugin_icon_foreground.png",
)
backgroundColor = "#101828"
}
surfaces {
catalog()
}
}Create a typed contribution in commonMain:
package org.example.catalog
import uk.shusek.suvio.extensions.sdk.*
@CatalogContribution
class ExamplePlugin : CatalogPlugin {
override suspend fun catalogs(): List<SuvioCatalogDescriptor> = TODO()
override suspend fun catalogPage(
catalogId: String,
mediaType: SuvioMediaType?,
pageToken: String?,
limit: Int,
searchTerm: String?,
filters: List<SuvioCatalogFilterSelection>,
sortId: String?,
sortDirection: SuvioCatalogSortDirection?,
): SuvioCatalogPageResponse = TODO()
override suspend fun mediaDetails(locator: MediaLocator): SuvioMediaDetails? = TODO()
}Put the selected metadata strings in
src/commonMain/composeResources/values/strings.xml and translations in
values-<locale>/strings.xml.
<resources>
<string name="plugin_name">Example Catalog</string>
<string name="plugin_description">Example media catalog.</string>
</resources>Build and execute tests with:
./gradlew suvioWasmWasmtimeTest packageSuvioPluginThe package contains exactly one executable:
components/plugin.wasm
All declared stable and preview surfaces are exports of that same Component Model component. Declaring more surfaces never creates additional Wasm files.
Stable for the 1.x line:
@CatalogContribution, CatalogPlugin, optional CatalogFacetsPlugin, and
CatalogEpisodesPlugin;@PlaybackContribution, PlaybackPlugin, and its optional interfaces;@SettingsContribution and hosted Settings UI.There is no root plugin class. Each annotated contribution is created only when one of its operations is dispatched. Metro constructor injection is an optional author choice; when Metro is applied, the SDK generates the invocation-scoped graph.
Preview surfaces require both surfaces.preview { ... } in Gradle and
@OptIn(ExperimentalSuvioPluginApi::class) in Kotlin:
Jellyfin is the stable reference plugin. MDBList is the preview reference
plugin. The executable all-surfaces example used by the release gate lives in
integration-tests/component-host-plugin.
The SDK is published under these module names:
plugin-apiplugin-runtime-wasiplugin-uiplugin-formatplugin-host-apiplugin-wituk.shusek.suvio.plugin.gradle.pluginPlugin authors do not add those dependencies manually. A manually versioned authoring dependency fails configuration with a readable error.
Generated Dokka HTML and a real Dokka JAR are produced by the documentation and publication tasks.
The SDK is source-available under the Suvio Plugin SDK License 1.0. Plugin authors retain ownership of their original code. GPLv3 plugins must include the Suvio SDK Linking Exception 1.0; see the license FAQ.