
GPU shader effects for Compose: Modifier-style API with built-in effects (blur, grayscale, pixelate, wave), type-safe parameters, animations, shader-factory caching, and custom shader support.
ShaderX is a Kotlin Multiplatform shader library for Jetpack Compose and Compose Multiplatform. Apply grayscale, blur, gradients, pixelation, and custom AGSL/SkSL effects to your UI on Android, iOS, desktop, and WebAssembly with Modifier.shaderEffect.
Documentation · Live playground · Quickstart · Effects · Samples · Contributing
Explore live effect controls, transform a camera preview into ASCII art, or make a movie carousel respond to every scroll. These recordings show the sample apps built with ShaderX.
| ShaderLab · Android | ShaderLab · WebAssembly |
|---|---|
![]() |
![]() |
| An effect playground with live parameter controls. Explore ShaderLab |
The same shared Compose UI in the browser. Try it in your browser |
| ASCIICamera | VerticalCarousel |
![]() |
![]() |
| Custom shaders on a live Android camera feed. Explore ASCIICamera |
Scroll-driven effects on movie cards. Explore VerticalCarousel |
Add Maven Central to your repositories in settings.gradle.kts:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}Add ShaderX to your shared module's build.gradle.kts:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.debanshu777:shaderx:0.1.4")
}
}
}For an Android-only Compose app, use the same dependency inside dependencies { ... }.
Use JDK 21, Kotlin 2.3.21, and Compose Multiplatform 1.10.3 as the starting toolchain. Android requires minSdk 33. See installation and version catalogs.
Release status:
0.1.4is published on Maven Central. It includes session-driven animation, texture uniforms, and 15 built-in effects. The guides describe this release and identify differences from0.1.3. See the release notes.
This complete composable takes your app's existing Painter, so it works with Compose resources or an image loader without relying on a particular resource name.
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import com.debanshu.shaderlab.shaderx.compose.shaderEffect
import com.debanshu.shaderlab.shaderx.effect.impl.GrayscaleEffect
@Composable
fun GrayscalePhoto(painter: Painter, modifier: Modifier = Modifier) {
Image(
painter = painter,
contentDescription = "Photo with a grayscale effect",
modifier = modifier.shaderEffect(GrayscaleEffect(intensity = 1f)),
)
}Replace GrayscaleEffect() with SepiaEffect(), NativeBlurEffect(radius = 8f), or PixelateEffect(pixelSize = 12f) from the same effect.impl package. The modifier can also transform text, cards, and other Compose content.
RuntimeShader on Android and Skia RuntimeEffect on iOS, JVM desktop, and Wasm.RuntimeShaderEffect interface to bring your own AGSL/SkSL source.ShaderResult or the modifier's onError callback.| Platform | Kotlin target / requirement | Backend | Multiple effects with +
|
|---|---|---|---|
| Android | API 33+ | AGSL / RuntimeShader
|
Supported |
| iOS |
iosArm64, iosSimulatorArm64
|
Skia / RuntimeEffect
|
Unsupported |
| Desktop | JVM; Windows, macOS, Linux | Skia / RuntimeEffect
|
Unsupported |
| Web |
wasmJs; browser with Wasm GC support |
Skia / RuntimeEffect
|
Unsupported |
Multi-effect chains on Skia return ShaderError.UnsupportedEffect. Android's current offline ImageProcessor path returns a processing failure; use the Compose modifier for Android rendering. See the platform and feature matrix before choosing an API.
| Available in | Effects |
|---|---|
| 0.1.3 |
GrayscaleEffect, SepiaEffect, GradientEffect, VignetteEffect, PixelateEffect, ChromaticAberrationEffect, InvertEffect, NativeBlurEffect, WaveEffect
|
| 0.1.4 | All of the above, plus AnimatedGradientEffect, PlasmaEffect, RippleEffect, VortexEffect, AudioVisualizerEffect, AudioDistortionEffect
|
The effect catalog covers parameters and examples. The Compose guide explains animation, Android effect chaining, and cache ownership.
| Sample | What it demonstrates | Run / preview |
|---|---|---|
| ShaderLab | Effect gallery, live controls, image loading, and audio effects | Playground · Setup · Android recording · Web recording |
| ASCIICamera | Custom shaders on an Android CameraX preview | Setup · Recording |
| VerticalCarousel | Scroll-driven shader parameters on movie cards | Setup and TMDB token · Recording |
Run the desktop gallery from a checkout with JDK 21 and the Android SDK configured:
./gradlew :samples:ShaderLab:composeApp:runPerformance checks cover native-resource disposal, rendered animation, bounded sample-image decoding, and reusable audio processing. Optional allocation diagnostics and the Android export host tests are documented in performance validation. The docs preview bundles the production Wasm playground; see local validation.
Compatibility checks cover the published modifier callback signatures, WaveEffect copying and destructuring, and custom factories without animation sessions. See API compatibility checks.
Bug reports, documentation fixes, and new effects are welcome. Read CONTRIBUTING.md, then open an issue with a reproducible example.
Every code change includes updates to this README and the affected documentation guides. Agent instructions map changes to guides, and CI checks that both are updated. The documentation site publishes automatically only after a pull request merges into main and its documentation build passes; see the maintainer guide for the workflow.
Maintainers publish from Actions → Release ShaderX → Run workflow, choosing prerelease, patch, minor, or major. The workflow calculates the version, tests the library, publishes to Maven Central, and creates a GitHub release with the dependency snippet. Stable releases require main; betas can use a feature branch. See the release workflow guide for setup and recovery. CI retains platform test reports, and browser tests wait for Skia initialization before running.
ShaderX is released under the Apache License 2.0.
ShaderX is a Kotlin Multiplatform shader library for Jetpack Compose and Compose Multiplatform. Apply grayscale, blur, gradients, pixelation, and custom AGSL/SkSL effects to your UI on Android, iOS, desktop, and WebAssembly with Modifier.shaderEffect.
Documentation · Live playground · Quickstart · Effects · Samples · Contributing
Explore live effect controls, transform a camera preview into ASCII art, or make a movie carousel respond to every scroll. These recordings show the sample apps built with ShaderX.
| ShaderLab · Android | ShaderLab · WebAssembly |
|---|---|
![]() |
![]() |
| An effect playground with live parameter controls. Explore ShaderLab |
The same shared Compose UI in the browser. Try it in your browser |
| ASCIICamera | VerticalCarousel |
![]() |
![]() |
| Custom shaders on a live Android camera feed. Explore ASCIICamera |
Scroll-driven effects on movie cards. Explore VerticalCarousel |
Add Maven Central to your repositories in settings.gradle.kts:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}Add ShaderX to your shared module's build.gradle.kts:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.debanshu777:shaderx:0.1.4")
}
}
}For an Android-only Compose app, use the same dependency inside dependencies { ... }.
Use JDK 21, Kotlin 2.3.21, and Compose Multiplatform 1.10.3 as the starting toolchain. Android requires minSdk 33. See installation and version catalogs.
Release status:
0.1.4is published on Maven Central. It includes session-driven animation, texture uniforms, and 15 built-in effects. The guides describe this release and identify differences from0.1.3. See the release notes.
This complete composable takes your app's existing Painter, so it works with Compose resources or an image loader without relying on a particular resource name.
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import com.debanshu.shaderlab.shaderx.compose.shaderEffect
import com.debanshu.shaderlab.shaderx.effect.impl.GrayscaleEffect
@Composable
fun GrayscalePhoto(painter: Painter, modifier: Modifier = Modifier) {
Image(
painter = painter,
contentDescription = "Photo with a grayscale effect",
modifier = modifier.shaderEffect(GrayscaleEffect(intensity = 1f)),
)
}Replace GrayscaleEffect() with SepiaEffect(), NativeBlurEffect(radius = 8f), or PixelateEffect(pixelSize = 12f) from the same effect.impl package. The modifier can also transform text, cards, and other Compose content.
RuntimeShader on Android and Skia RuntimeEffect on iOS, JVM desktop, and Wasm.RuntimeShaderEffect interface to bring your own AGSL/SkSL source.ShaderResult or the modifier's onError callback.| Platform | Kotlin target / requirement | Backend | Multiple effects with +
|
|---|---|---|---|
| Android | API 33+ | AGSL / RuntimeShader
|
Supported |
| iOS |
iosArm64, iosSimulatorArm64
|
Skia / RuntimeEffect
|
Unsupported |
| Desktop | JVM; Windows, macOS, Linux | Skia / RuntimeEffect
|
Unsupported |
| Web |
wasmJs; browser with Wasm GC support |
Skia / RuntimeEffect
|
Unsupported |
Multi-effect chains on Skia return ShaderError.UnsupportedEffect. Android's current offline ImageProcessor path returns a processing failure; use the Compose modifier for Android rendering. See the platform and feature matrix before choosing an API.
| Available in | Effects |
|---|---|
| 0.1.3 |
GrayscaleEffect, SepiaEffect, GradientEffect, VignetteEffect, PixelateEffect, ChromaticAberrationEffect, InvertEffect, NativeBlurEffect, WaveEffect
|
| 0.1.4 | All of the above, plus AnimatedGradientEffect, PlasmaEffect, RippleEffect, VortexEffect, AudioVisualizerEffect, AudioDistortionEffect
|
The effect catalog covers parameters and examples. The Compose guide explains animation, Android effect chaining, and cache ownership.
| Sample | What it demonstrates | Run / preview |
|---|---|---|
| ShaderLab | Effect gallery, live controls, image loading, and audio effects | Playground · Setup · Android recording · Web recording |
| ASCIICamera | Custom shaders on an Android CameraX preview | Setup · Recording |
| VerticalCarousel | Scroll-driven shader parameters on movie cards | Setup and TMDB token · Recording |
Run the desktop gallery from a checkout with JDK 21 and the Android SDK configured:
./gradlew :samples:ShaderLab:composeApp:runPerformance checks cover native-resource disposal, rendered animation, bounded sample-image decoding, and reusable audio processing. Optional allocation diagnostics and the Android export host tests are documented in performance validation. The docs preview bundles the production Wasm playground; see local validation.
Compatibility checks cover the published modifier callback signatures, WaveEffect copying and destructuring, and custom factories without animation sessions. See API compatibility checks.
Bug reports, documentation fixes, and new effects are welcome. Read CONTRIBUTING.md, then open an issue with a reproducible example.
Every code change includes updates to this README and the affected documentation guides. Agent instructions map changes to guides, and CI checks that both are updated. The documentation site publishes automatically only after a pull request merges into main and its documentation build passes; see the maintainer guide for the workflow.
Maintainers publish from Actions → Release ShaderX → Run workflow, choosing prerelease, patch, minor, or major. The workflow calculates the version, tests the library, publishes to Maven Central, and creates a GitHub release with the dependency snippet. Stable releases require main; betas can use a feature branch. See the release workflow guide for setup and recovery. CI retains platform test reports, and browser tests wait for Skia initialization before running.
ShaderX is released under the Apache License 2.0.