Ship an entire Maven repository as one artifact. Consumers use it exactly like a normal Maven repository.
Capsule packs every module, target, and variant of your SDK into a single signed file (.cap). You
publish one artifact. Your consumers write plain implementation("dev.ketoy.vm:ketoy-runtime") and never
know the difference. The packaging is invisible.
Status: alpha (
0.1.2). Both plugins are live on the Gradle Plugin Portal:dev.ketoy.capsule.publishanddev.ketoy.capsule.resolve.
Publish (SDK root):
plugins {
id("com.vanniktech.maven.publish") version "0.30.0"
id("dev.ketoy.capsule.publish") version "0.1.2"
}
capsule {
archive("com.acme:acme-sdk") // the one .cap coordinate
signingKeyFile.set(layout.projectDirectory.file("keys/capsule.pkcs8")) // Ed25519, signs the .cap
}Consume (one line in settings.gradle.kts):
plugins { id("dev.ketoy.capsule.resolve") version "0.1.2" }
capsule { sdk("dev.ketoy.vm:ketoy-sdk:0.4.21-alpha") }Then depend on the modules normally. They resolve from the archive like any dependency:
implementation(platform(libs.ketoy.bom))
implementation(libs.ketoy.runtime)
implementation(libs.ketoy.koin)Shipping a real SDK means managing a sprawl of artifacts. Every module, every Kotlin Multiplatform target, every variant becomes its own coordinate with its own jar, POM, module metadata, sources, and signatures. That sprawl has to be built, signed, uploaded, mirrored, and kept in sync on every release. Capsule collapses it into one file.
- One thing to ship. A single
.capis what you sign, upload, mirror, or attach to a release. Distribution stops scaling with your module count. - Consumers resolve normally. The
.capexplodes into a byte-identical local Maven repository. R8, ProGuard, AAR consumer rules, Gradle Module Metadata, and variant selection all work unchanged. - Built for large and Kotlin Multiplatform projects. Add modules and targets freely. Your published footprint stays one artifact.
- Signed and scannable. Every
.capcarries an Ed25519 signature the resolver verifies, plus a CycloneDX SBOM so the bundled modules stay vulnerability scannable.
Maven Central's monthly file limit is the sharpest edge of this sprawl, and Capsule turns a release from hundreds of files into a small constant. That is a benefit, not the point. The point is that your whole SDK travels as one artifact.
Capsule ships the real Ketoy SDK to Maven Central:
| Files to Maven Central | |
|---|---|
| Normal per-module publication | 1295 |
With Capsule (.cap + BOM + catalog + SBOM) | 95 |
17 library modules pack into one 2.7 MB signed .cap. The Central release is 3 coordinates,
validated first try, and stays a small constant no matter how many modules the SDK grows to.
| Guide | What's in it |
|---|---|
| Overview | What Capsule is, the model, when to reach for it |
| Publishing | Keys, single and multi module, exclude, pre-check, publish |
| Consuming | The resolver, sdk(...), public keys, using the modules |
| Reference | Every DSL option, the CLI, the .cap format, security |
| How it works | The internals, end to end |
| Module | What it is |
|---|---|
capsule-format | The .cap container: writer, reader, manifest, Ed25519 signing, SBOM, CLI. Zero external deps. |
capsule-provision | Pure content-addressed explode of a .cap into a local repo. |
capsule-publish-plugin | dev.ketoy.capsule.publish, the publisher plugin, built on vanniktech. |
capsule-resolve-plugin | dev.ketoy.capsule.resolve, the consumer settings plugin. |
./gradlew build # compile and all tests
e2e/run-roundtrip.sh # publish then resolve round-trip, signature enforcedApache-2.0.