gradle-expert
Build optimization, dependency resolution, and multi-module KMP troubleshooting for AmethystMultiplatform. Use when working with: (1) Gradle build files (build.gradle.kts, settings.gradle), (2) Version catalog (libs.versions.toml), (3) Build errors and dependency conflicts, (4) Module dependencies and source sets, (5) Desktop packaging (DMG/MSI/DEB), (6) Build performance optimization, (7) Proguard/R8 configuration, (8) Common KMP + Android Gradle issues (Compose conflicts, secp256k1 JNI variants, source set problems).
Install
mkdir -p .claude/skills/gradle-expert && curl -L -o skill.zip "https://mcp.directory/api/skills/download/5381" && unzip -o skill.zip -d .claude/skills/gradle-expert && rm skill.zipInstalls to .claude/skills/gradle-expert
About this skill
Gradle Expert
Build system expertise for AmethystMultiplatform's 4-module KMP architecture. Focus: practical troubleshooting, dependency resolution, and project-specific optimizations.
Build Architecture Mental Model
Think of this project as 4 layers:
┌─────────────┬─────────────┐
│ :amethyst │ :desktopApp │ ← Platform apps (navigation, layouts)
│ (Android) │ (JVM) │
└──────┬──────┴──────┬──────┘
│ │
└──────┬──────┘
▼
┌─────────────┐
│ :commons │ ← Shared UI (KMP with jvmAndroid)
│ (KMP UI) │
└──────┬──────┘
▼
┌─────────────┐
│ :quartz │ ← Core library (KMP: Android/JVM/iOS)
│(KMP Library)│
└─────────────┘
Key insight: Dependencies flow DOWN. Lower modules never depend on upper modules. This enables code sharing without circular dependencies.
The jvmAndroid pattern: Unique to this project. A custom source set between commonMain and {androidMain, jvmMain} for JVM-specific code shared by Android and Desktop. Not standard KMP, but critical for this architecture.
Version Catalog Philosophy
All dependencies centralized in gradle/libs.versions.toml. Think "single source of truth."
Pattern:
[versions]
kotlin = "2.3.0"
[libraries]
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
[plugins]
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
Usage:
dependencies {
implementation(libs.okhttp) // Type-safe, IDE-autocompleted
}
Critical alignments:
- Kotlin ecosystem: All Kotlin plugins MUST share same version
- Compose ecosystem: Compose Multiplatform version → Kotlin version (check compatibility matrix)
- secp256k1 variants: All three variants (common, jni-android, jni-jvm) MUST share same version
See references/version-catalog-guide.md for comprehensive patterns.
Common Build Tasks
Quick Reference
# Full builds
./gradlew build # All modules
./gradlew clean build # Clean build
# Desktop
./gradlew :desktopApp:run # Run desktop app
./gradlew :desktopApp:packageDmg # macOS package
# Module-specific
./gradlew :quartz:build # KMP library only
./gradlew :commons:build # Shared UI only
# Analysis
./gradlew dependencies # Dependency tree
./gradlew build --scan # Online diagnostics
See references/build-commands.md for comprehensive command reference.
Module Structure & Dependencies
Dependency Flow
Desktop build chain:
:desktopApp → :commons (jvmMain) → :quartz (jvmMain → jvmAndroid → commonMain)
Android build chain:
:amethyst → :commons (androidMain) → :quartz (androidMain → jvmAndroid → commonMain)
Key source set pattern (quartz & commons):
commonMain # Truly cross-platform code
│
├─ jvmAndroid # JVM-specific, shared by Android + Desktop
│ ├─ androidMain
│ └─ jvmMain
│
└─ iosMain # iOS-specific (quartz only)
Dependency config types:
- Use
apiwhen types appear in module's public API or expect/actual declarations - Use
implementationfor internal implementation details - Example: quartz exposes secp256k1 (
api), but hides okhttp (implementation)
See references/dependency-graph.md for module visualization and transitive dependency flow.
Critical Dependency Patterns
1. secp256k1 (Crypto Library)
The problem: KMP library with platform-specific JNI bindings. Wrong variant = runtime crash.
Pattern:
// commonMain - API only
api(libs.secp256k1.kmp.common)
// androidMain - Android JNI
api(libs.secp256k1.kmp.jni.android)
// jvmMain - Desktop JVM JNI
implementation(libs.secp256k1.kmp.jni.jvm)
Why api in androidMain? Types leak to consumers (:amethyst).
Common error: Desktop using jni-android variant → UnsatisfiedLinkError: no secp256k1jni in java.library.path
Fix: Check source set dependencies. jvmMain must use jni-jvm, never jni-android.
2. JNA (for LibSodium Encryption)
The problem: Android needs AAR packaging, JVM needs JAR. Same library, different artifact types.
Pattern:
// androidMain
implementation("com.goterl:lazysodium-android:5.2.0@aar") // @aar explicit
implementation("net.java.dev.jna:jna:5.18.1@aar")
// jvmMain
implementation(libs.lazysodium.java) // JAR implicit
implementation(libs.jna)
Critical: Never put JNA in jvmAndroid or commonMain. Platform-specific packaging only.
3. Compose Versions
The problem: Two Compose ecosystems (Multiplatform + AndroidX) must align, or duplicate classes.
Current project config:
composeMultiplatform = "1.9.3" # Plugin + runtime
composeBom = "2025.12.01" # AndroidX Compose BOM
kotlin = "2.3.0"
Rule: Compose Multiplatform version must be compatible with Kotlin version. Check: https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compatibility-and-versioning.html
In KMP modules (quartz, commons):
// ✅ Use Compose Multiplatform
implementation(compose.ui)
implementation(compose.material3)
// ❌ DON'T use AndroidX BOM in KMP modules
// implementation(libs.androidx.compose.bom)
In Android-only modules (amethyst):
// Can use AndroidX BOM
val composeBom = platform(libs.androidx.compose.bom)
implementation(composeBom)
Desktop Packaging Basics
TargetFormat options:
// In desktopApp/build.gradle.kts
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "Amethyst"
packageVersion = "1.0.0"
macOS {
bundleID = "com.vitorpamplona.amethyst.desktop"
iconFile.set(project.file("src/jvmMain/resources/icon.icns"))
}
}
Package tasks:
./gradlew :desktopApp:packageDmg # macOS
./gradlew :desktopApp:packageMsi # Windows
./gradlew :desktopApp:packageDeb # Linux
Output locations:
- macOS:
desktopApp/build/compose/binaries/main/dmg/ - Windows:
desktopApp/build/compose/binaries/main/msi/ - Linux:
desktopApp/build/compose/binaries/main/deb/
Icon requirements:
- macOS:
.icns(multi-resolution: 512, 256, 128, 32) - Windows:
.ico(256, 128, 64, 32, 16) - Linux:
.png(512x512)
Common issues:
- Main class not found → Verify
mainClass = "...MainKt"(Kotlin addsKtsuffix) - Native libs missing → Ensure secp256k1-kmp-jni-jvm in dependencies
- Icon not found → Check file exists at path, use absolute path if needed
Build Performance Optimization
Add to gradle.properties:
# Daemon (faster subsequent builds)
org.gradle.daemon=true
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g
# Parallel execution (multi-module speedup)
org.gradle.parallel=true
org.gradle.workers.max=8
# Caching (incremental builds)
org.gradle.caching=true
org.gradle.configuration-cache=true
# Kotlin daemon
kotlin.incremental=true
kotlin.daemon.jvmargs=-Xmx2g
Impact: Typically 30-50% faster builds after first run.
Measure impact:
./gradlew clean build --profile
# Report: build/reports/profile/profile-<timestamp>.html
When to clean build:
- After changing version catalog
- After adding/removing source sets
- When seeing unexplained errors
When NOT to clean:
- Regular development iteration
- Small code changes
- Incremental compilation works fine
Use script: scripts/analyze-build-time.sh for automated profiling.
Troubleshooting: Practical Patterns
Pattern 1: Version Conflict
Symptom: Duplicate class or NoSuchMethodError
Diagnosis:
./gradlew dependencyInsight --dependency <library-name>
Fix options:
- Align versions in libs.versions.toml (preferred)
- Force resolution:
configurations.all {
resolutionStrategy {
force(libs.okhttp.get().toString())
}
}
Pattern 2: Source Set Issues
Symptom: Unresolved reference to JVM library in shared code
Diagnosis: Check source set hierarchy. JVM-only libs (jackson, okhttp) can't be in commonMain.
Fix: Move to jvmAndroid or platform-specific source set.
// ❌ Wrong
commonMain {
dependencies {
implementation(libs.jackson.module.kotlin) // JVM-only!
}
}
// ✅ Correct
val jvmAndroid = create("jvmAndroid") {
dependsOn(commonMain.get())
dependencies {
api(libs.jackson.module.kotlin) // JVM code, shared by Android + Desktop
}
}
Pattern 3: Proguard Stripping Native Libs
Symptom: NoClassDefFoundError for secp256k1, JNA, or LibSodium in release builds
Fix: Update proguard rules in quartz/proguard-rules.pro:
# Native libraries
-keep class fr.acinq.secp256k1.** { *; }
-keep class com.goterl.lazysodium.** { *; }
-keep class com.sun.jna.** { *; }
# Jackson (reflection-based)
-keep class com.vitorpamplona.quartz.** { *; }
-keepattributes *Annotation*
-keepattributes Signature
Pattern 4: Compose Compiler Mismatch
Symptom: IllegalStateException: Version mismatch: runtime 1.10.0 but compiler 1.9.0
Fix: Update Compose Multiplatform version in libs.versions.toml to match Kotlin version compatibility.
Check: https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compatibility-and-versioning.html
Pattern 5: Wrong JVM Target
Symptom: Unsupported class file major version 65
Fix: Ensure Java 21 everywhere:
# Check current Java
java -version # Should show 21
# Set JAVA_HOME
export JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home
# Stop Gradle daemon to pick up new Java
./gradlew --stop
Verify all build files use JVM 21:
kotlin {
jvm {
compilerOptions {
---
*Content truncated.*
More by vitorpamplona
View all skills by vitorpamplona →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversSearch any codebase or documentation, including Git Hub repositories, with Probe's optimized, auto-updating search engin
Access 135+ animated React UI components from ReactBits.dev with intelligent caching, dependency detection, and quality
Skill Management is workflow automation software that builds, organizes, and executes maintainable software workflows wi
Connect Triple Whale to analyze e-commerce sales, build actionable sales dashboards, and use marketing attribution tools
Build persistent semantic networks for enterprise & engineering data management. Enable data persistence and memory acro
Uno Platform — Documentation and prompts for building cross-platform .NET apps with a single codebase. Get guides, sampl
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.