
Hand-drawn, sketch-style UI components and shapes for Compose, with customizable stroke, jitter/randomness, sketch modifiers (hachure, indicator), plus ready controls like cards, buttons, fields.
A Compose Multiplatform UI library of components with a hand-drawn, sketch-style appearance.
Designed to bring playful, human touches to your Compose UIs while keeping them fully customizable and production-ready.
A Compose Multiplatform port of EranBoudjnah/sketch, which is Jetpack Compose (Android) only. All the drawing logic is his; this fork moves it to
commonMainand publishes Android, iOS and Desktop artifacts. MIT, same as upstream.
https://github.com/user-attachments/assets/56c42ec7-4ed5-45e5-89ec-19d6a91edee9
| Target | Status |
|---|---|
| Android | ✅ |
| iOS (arm64, x64, sim) | ✅ |
| Desktop (JVM) | ✅ |
| Minimum | |
|---|---|
| Kotlin | 2.2.21 |
| Compose Multiplatform | 1.10.0 |
Android minSdk
|
24 |
| JDK (to build) | 17 |
Kotlin/Native klibs record the compiler that produced them, so a consumer on an older Kotlin than the one this was built with fails to resolve rather than degrading gracefully. If you see a klib or metadata version error, align your Kotlin version first.
| Feature | Description |
|---|---|
| ✏️ Sketch look & feel | Adds a hand-drawn, playful aesthetic to your Compose components. |
| 🧩 Composable components | Works with all your standard Compose UI code. |
| 🎨 Customizable styles | Control stroke width, color, randomness, and more. |
| 💡 Lightweight | No dependencies beyond Compose and androidx.annotation. |
| 🌍 Multiplatform | One commonMain dependency covers Android, iOS and Desktop. |
Add Sketch KMP to your Gradle project:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.nowjordanhappy:sketch-kmp:<latest-version>")
}
}
}💡 Replace <latest-version> with the latest release from Releases
Use Sketch components just like any other Compose UI elements.
import io.github.nowjordanhappy.sketchkmp.Card
import io.github.nowjordanhappy.sketchkmp.SketchCapsuleShape
@Composable
fun ExampleScreen() {
Card {
Text(text = "Hello, Sketch!")
Spacer(modifier = Modifier.height(16.dp))
Button(
shape = SketchCapsuleShape(),
onClick = { /* TODO */ }
) {
Text("Click Me!")
}
}
}Every shape takes a randomSeed. It defaults to 0, which is deterministic — so a row of
same-sized components renders the same wobble and reads as a repeating texture rather than
hand-drawing. Vary it per instance:
shape = remember(label) { SketchRoundedCornerShape(16.dp, randomSeed = label.hashCode()) }Card — sketchy card containerCheckbox, TriStateCheckbox — checkboxes with a sketched boxCircularProgressIndicator, LinearProgressIndicator — range of sketchy progress indicatorsHorizontalDivider, VerticalDivider — sketched dividersRadioButton — a sketched radio buttonSketchDialog — dialog with sketchy outlinesSlider, RangeSlider — sliders with sketched tracks and handlesSurface — sketchy surface containerSwitch — sketch-styled switchTextField — input field with sketched underlineUseful for turning common composables sketchy.
SketchCapsuleShape — capsule-shaped sketch, with circles on the left and rightSketchCircleShape — sketched circleSketchRectangleShape — plain rectangle with sketchy edgesSketchRoundedCornerShape — sketched round-cornered rectangleAdd a sketchy appearance to any composable.
hachure — hatch pattern backgroundsketchIndicatorLine — sketched indicator line, as used by TextField
The :app module is a Compose Multiplatform showcase of every component, sharing one UI across
all three platforms from commonMain.
Android Studio picks up run configurations for all three: app (Android), app [desktop] and iosApp. From the command line:
./gradlew :app:run # Desktop
./gradlew :app:installDebug # AndroidiOS lives in iosApp/ as a normal Xcode project, so it opens in Xcode and Android Studio like
any other KMP project. It embeds the SketchSample framework and hosts MainViewController()
in a SwiftUI UIViewControllerRepresentable. To build it outside the IDE:
xcodebuild -project iosApp/iosApp.xcodeproj -scheme iosApp \
-destination "platform=iOS Simulator,name=iPhone 16 Pro" build./gradlew :app:desktopTest renders the UI headlessly to app/build/snapshots/*.png — no
device, simulator or screen-recording permission needed.
TextField takes an errorMessage: String (default "Invalid input"). Upstream read this
from androidx.compose.ui.R, a private Android resource with no multiplatform equivalent.
Passing a localised string keeps the accessibility announcement translated.@Preview. androidx.compose.ui.tooling.preview is Android-only.Outline cache can hit.Everything else matches upstream 0.3.0. See CHANGELOG.md.
Most Sketch composables conform to the Compose standards, and should be intuitive if you're familiar with the common composables.
Contributions are welcome! Check out the Contributing Guidelines before submitting a pull request.
For changes to the drawing logic itself, consider sending them upstream too.
Reach out via my profile page.
MIT — © 2025 Eran Boudjnah (original work), © 2026 Jordan Rojas (multiplatform port).
A Compose Multiplatform UI library of components with a hand-drawn, sketch-style appearance.
Designed to bring playful, human touches to your Compose UIs while keeping them fully customizable and production-ready.
A Compose Multiplatform port of EranBoudjnah/sketch, which is Jetpack Compose (Android) only. All the drawing logic is his; this fork moves it to
commonMainand publishes Android, iOS and Desktop artifacts. MIT, same as upstream.
https://github.com/user-attachments/assets/56c42ec7-4ed5-45e5-89ec-19d6a91edee9
| Target | Status |
|---|---|
| Android | ✅ |
| iOS (arm64, x64, sim) | ✅ |
| Desktop (JVM) | ✅ |
| Minimum | |
|---|---|
| Kotlin | 2.2.21 |
| Compose Multiplatform | 1.10.0 |
Android minSdk
|
24 |
| JDK (to build) | 17 |
Kotlin/Native klibs record the compiler that produced them, so a consumer on an older Kotlin than the one this was built with fails to resolve rather than degrading gracefully. If you see a klib or metadata version error, align your Kotlin version first.
| Feature | Description |
|---|---|
| ✏️ Sketch look & feel | Adds a hand-drawn, playful aesthetic to your Compose components. |
| 🧩 Composable components | Works with all your standard Compose UI code. |
| 🎨 Customizable styles | Control stroke width, color, randomness, and more. |
| 💡 Lightweight | No dependencies beyond Compose and androidx.annotation. |
| 🌍 Multiplatform | One commonMain dependency covers Android, iOS and Desktop. |
Add Sketch KMP to your Gradle project:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.nowjordanhappy:sketch-kmp:<latest-version>")
}
}
}💡 Replace <latest-version> with the latest release from Releases
Use Sketch components just like any other Compose UI elements.
import io.github.nowjordanhappy.sketchkmp.Card
import io.github.nowjordanhappy.sketchkmp.SketchCapsuleShape
@Composable
fun ExampleScreen() {
Card {
Text(text = "Hello, Sketch!")
Spacer(modifier = Modifier.height(16.dp))
Button(
shape = SketchCapsuleShape(),
onClick = { /* TODO */ }
) {
Text("Click Me!")
}
}
}Every shape takes a randomSeed. It defaults to 0, which is deterministic — so a row of
same-sized components renders the same wobble and reads as a repeating texture rather than
hand-drawing. Vary it per instance:
shape = remember(label) { SketchRoundedCornerShape(16.dp, randomSeed = label.hashCode()) }Card — sketchy card containerCheckbox, TriStateCheckbox — checkboxes with a sketched boxCircularProgressIndicator, LinearProgressIndicator — range of sketchy progress indicatorsHorizontalDivider, VerticalDivider — sketched dividersRadioButton — a sketched radio buttonSketchDialog — dialog with sketchy outlinesSlider, RangeSlider — sliders with sketched tracks and handlesSurface — sketchy surface containerSwitch — sketch-styled switchTextField — input field with sketched underlineUseful for turning common composables sketchy.
SketchCapsuleShape — capsule-shaped sketch, with circles on the left and rightSketchCircleShape — sketched circleSketchRectangleShape — plain rectangle with sketchy edgesSketchRoundedCornerShape — sketched round-cornered rectangleAdd a sketchy appearance to any composable.
hachure — hatch pattern backgroundsketchIndicatorLine — sketched indicator line, as used by TextField
The :app module is a Compose Multiplatform showcase of every component, sharing one UI across
all three platforms from commonMain.
Android Studio picks up run configurations for all three: app (Android), app [desktop] and iosApp. From the command line:
./gradlew :app:run # Desktop
./gradlew :app:installDebug # AndroidiOS lives in iosApp/ as a normal Xcode project, so it opens in Xcode and Android Studio like
any other KMP project. It embeds the SketchSample framework and hosts MainViewController()
in a SwiftUI UIViewControllerRepresentable. To build it outside the IDE:
xcodebuild -project iosApp/iosApp.xcodeproj -scheme iosApp \
-destination "platform=iOS Simulator,name=iPhone 16 Pro" build./gradlew :app:desktopTest renders the UI headlessly to app/build/snapshots/*.png — no
device, simulator or screen-recording permission needed.
TextField takes an errorMessage: String (default "Invalid input"). Upstream read this
from androidx.compose.ui.R, a private Android resource with no multiplatform equivalent.
Passing a localised string keeps the accessibility announcement translated.@Preview. androidx.compose.ui.tooling.preview is Android-only.Outline cache can hit.Everything else matches upstream 0.3.0. See CHANGELOG.md.
Most Sketch composables conform to the Compose standards, and should be intuitive if you're familiar with the common composables.
Contributions are welcome! Check out the Contributing Guidelines before submitting a pull request.
For changes to the drawing logic itself, consider sending them upstream too.
Reach out via my profile page.
MIT — © 2025 Eran Boudjnah (original work), © 2026 Jordan Rojas (multiplatform port).