
Annotation-driven screenshot testing and interactive component browser for Compose: collects annotated composables into a registry, renders via real Compose runtime, records PNG goldens and diffs.
Screenshot tests for Compose Multiplatform on a plain JVM. One annotation on a composable gives a golden-file test and an entry in a component browser — rendered through Compose Desktop/Skiko, with no emulator, no AVD and no layoutlib.
@ViddikScreenshot(name = "Primary", group = "Buttons")
@Composable
fun PrimaryButton() {
MaterialTheme(typography = viddikTypography()) {
Button(onClick = {}) { Text("Continue") }
}
}./gradlew :yourModule:viddikRecord # write the goldens
./gradlew :yourModule:viddikVerify # compare against them
./gradlew :yourModule:viddikShowroom # browse the components in a window// settings.gradle.kts — mavenCentral() in both blocks, google() beside the second
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
}
}
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}// build.gradle.kts of the module that holds the fixtures
plugins {
id("com.google.devtools.ksp") version "<KSP_VERSION>" // must match your Kotlin compiler version
id("io.github.youndie.viddik") version "0.7.0"
}That is the whole setup: the plugin adds the dependencies, the KSP processor and the tasks, with the names your module's shape needs. viddik 0.7 works with Compose Multiplatform 1.12, Kotlin 2.4 and JDK 21. Options, compatibility and the setup without the plugin: docs/configuration.md.
Measured in screenshot-bench: the same generated composables at 360×640, each tool set up as its own documentation says, one build machine (20 cores, Linux), medians. viddik 0.6.1.45 for the speed rows, which is the code of 0.7.0 there.
| viddik | Roborazzi, desktop | Roborazzi, Robolectric | Paparazzi | |
|---|---|---|---|---|
| Renderer | Skiko | Skiko | Android framework | layoutlib |
| Verify 1000 screenshots, one JVM | 25.1 s | 29.6 s | 41.5 s | 28.7 s |
| Verify 2000 screenshots, four forks | 14.8 s | 17.9 s | 35.9 s | 22.7 s |
| Edit a component, record one golden (N=1000) | 3.3 s | 2.8 s | 7.4 s | 5.5 s |
| Linux goldens verified on macOS (N=50) | 50/50 pass, 38 byte-identical | 0/50 pass | 50/50, byte-identical | 50/50, byte-identical |
| A full stop added to a heading, default settings | 2/10 caught | 10/10 | 10/10 | 2/10 |
On large suites the two Skiko tools and Paparazzi are within a few seconds of each other; the
edit-and-record cycle is where they differ most. viddik's goldens travel between operating systems on
Skiko, where Roborazzi's do not — the Android renderers get that for free. The price is a tolerance:
at the default 0.05% a 12-pixel change on a full screen passes; with tolerancePercent = 0.0 it is
caught and the cross-OS goldens still pass (how a comparison decides).
@ViddikScreenshot, or @Preview metadata read off the same function, multipreviews,
@PreviewParameter, dark variants, one theme for all of them through @PreviewWrapper.
docs/fixtures.md
--component selects one fixture; one scene, two forks and a KSP that ignores body edits by
default. docs/running.md
viddikTypography()) does the rest. docs/portability.md
API reference: youndie.github.io/viddik. Release notes: GitHub releases.
MIT, see LICENSE.
Screenshot tests for Compose Multiplatform on a plain JVM. One annotation on a composable gives a golden-file test and an entry in a component browser — rendered through Compose Desktop/Skiko, with no emulator, no AVD and no layoutlib.
@ViddikScreenshot(name = "Primary", group = "Buttons")
@Composable
fun PrimaryButton() {
MaterialTheme(typography = viddikTypography()) {
Button(onClick = {}) { Text("Continue") }
}
}./gradlew :yourModule:viddikRecord # write the goldens
./gradlew :yourModule:viddikVerify # compare against them
./gradlew :yourModule:viddikShowroom # browse the components in a window// settings.gradle.kts — mavenCentral() in both blocks, google() beside the second
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
}
}
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}// build.gradle.kts of the module that holds the fixtures
plugins {
id("com.google.devtools.ksp") version "<KSP_VERSION>" // must match your Kotlin compiler version
id("io.github.youndie.viddik") version "0.7.0"
}That is the whole setup: the plugin adds the dependencies, the KSP processor and the tasks, with the names your module's shape needs. viddik 0.7 works with Compose Multiplatform 1.12, Kotlin 2.4 and JDK 21. Options, compatibility and the setup without the plugin: docs/configuration.md.
Measured in screenshot-bench: the same generated composables at 360×640, each tool set up as its own documentation says, one build machine (20 cores, Linux), medians. viddik 0.6.1.45 for the speed rows, which is the code of 0.7.0 there.
| viddik | Roborazzi, desktop | Roborazzi, Robolectric | Paparazzi | |
|---|---|---|---|---|
| Renderer | Skiko | Skiko | Android framework | layoutlib |
| Verify 1000 screenshots, one JVM | 25.1 s | 29.6 s | 41.5 s | 28.7 s |
| Verify 2000 screenshots, four forks | 14.8 s | 17.9 s | 35.9 s | 22.7 s |
| Edit a component, record one golden (N=1000) | 3.3 s | 2.8 s | 7.4 s | 5.5 s |
| Linux goldens verified on macOS (N=50) | 50/50 pass, 38 byte-identical | 0/50 pass | 50/50, byte-identical | 50/50, byte-identical |
| A full stop added to a heading, default settings | 2/10 caught | 10/10 | 10/10 | 2/10 |
On large suites the two Skiko tools and Paparazzi are within a few seconds of each other; the
edit-and-record cycle is where they differ most. viddik's goldens travel between operating systems on
Skiko, where Roborazzi's do not — the Android renderers get that for free. The price is a tolerance:
at the default 0.05% a 12-pixel change on a full screen passes; with tolerancePercent = 0.0 it is
caught and the cross-OS goldens still pass (how a comparison decides).
@ViddikScreenshot, or @Preview metadata read off the same function, multipreviews,
@PreviewParameter, dark variants, one theme for all of them through @PreviewWrapper.
docs/fixtures.md
--component selects one fixture; one scene, two forks and a KSP that ignores body edits by
default. docs/running.md
viddikTypography()) does the rest. docs/portability.md
API reference: youndie.github.io/viddik. Release notes: GitHub releases.
MIT, see LICENSE.