docs / Native
Native Libraries (.vsklib)
The .vsklib library system: libraries.json, the curated registry, vesk add/install/update/remove, auto-generated bindings, and using Kotlin libraries from .vsk.
Native apps can install real Kotlin/Android libraries and use them from `.vsk` files. Installed libraries are tracked in a committed `libraries.json` manifest, resolved against a curated `.vsklib` registry (for common libraries like Coil, Retrofit, and Room), with auto-generated typed bindings for anything else.
The two file surfaces
| File | Role |
|---|---|
| libraries.json | Committed manifest of installed libraries — like package.json. Written only by `vesk add/remove/update/install`. |
| .vsklib/ | Gitignored, disposable per-library record cache (AAR metadata, signatures, generated .d.ts declarations). |
Installing a library
# Install from the curated registry by id
vesk-native add lottie
vesk-native add coil
# Pin a version
vesk-native add lottie@6.5.2
# Bare Maven coordinates (auto-generates a typed binding)
vesk-native add com.squareup.okhttp3:okhttp
vesk-native add com.google.code.gson:gson@2.11.0
- Spec forms: `id`, `id@version`, `group:artifact`, `group:artifact@version` (`parseLibrarySpec`).
- Curated registry records are trusted verbatim; unknown `group:artifact` coordinates re-download the AAR/JAR and auto-generate a binding.
- The next build derives the library's gradle dependency, manifest permissions, and minimum SDK automatically.
- The app's `minSdk` is raised to the max across installed libraries — never a `tools:overrideLibrary` workaround.
libraries.json format
{
"version": 1,
"libraries": {
"lottie": {
"id": "lottie",
"name": "Lottie",
"description": "Airbnb Lottie animations for Compose",
"group": "essential",
"artifact": "com.airbnb.android:lottie-compose",
"version": "6.5.2",
"gradle": ["com.airbnb.android:lottie-compose:6.5.2"],
"multiplatform": false,
"permissions": [],
"exports": ["LottieComposition"],
"libType": "utility",
"essential": true,
"curated": true
}
}
}
- `gradle` — the `implementation` dependencies added to the build.
- `multiplatform` — true when the library publishes a Gradle common variant (`metadataApiElements`); decides whether importing pages land in `commonMain` vs `androidMain`.
- `permissions` — manifest permissions the library needs, merged with the usage scan.
- `exports` — composable tags / JS exports the library makes available to `.vsk`.
- `minSdk` — raised across installed libraries.
- `esssential` / `curated` — registry-authoring flags.
Using a library from .vsk
A library is only in scope in a file that explicitly imports it — installing a library never puts its tags in every page:
import { LottieComposition } from '@vesk/lottie'
export component LibExample() {
<LottieComposition src="/animations/loading.json" class="w-40 h-40" />
}
- Import specifier is always `@vesk/<libraryId>`.
- The typed `.d.ts` declarations are regenerated into `.vsklib/` on every add/install, giving editor autocomplete and typecheck coverage.
- Binding auto-generation parses the AAR's Kotlin @Metadata, class files, and AndroidManifest.xml to produce composable tags and signatures — never guessed from the name.
Curated registry
The registry ships committed `.vsklib` records in categories, authored from real library metadata — never invented:
| Category | Libraries |
|---|---|
| animations | animation-core, animation-graphics, material-ripple, shimmer |
| charts | vico, ycharts |
| device | billing, biometric, camera-camera2, camera-lifecycle, firebase-messaging, in-app-review, media3-exoplayer, mlkit-barcode, play-services-auth, play-services-location, play-services-maps |
| essential | coil, datastore, gson, kotlinx-serialization, lottie, moshi, okhttp, retrofit, room, workmanager |
| icons | icons-lucide, material-icons |
| images | coil3, coil-gif, coil-svg, coil-video, exifinterface, glide, glide-compose |
| json | jackson |
| network | apollo, chucker, ktor-client, okhttp-logging, okio, picasso, retrofit-gson, retrofit-moshi |
| tools | accompanist-permissions, flexbox, leakcanary, palette, timber, zxing |
| utilities | activity-compose, browser, constraintlayout-compose, core-ktx, coroutines, datetime, foundation, foundation-layout, immutable-collections, material, material3, navigation, preference-ktx, security-crypto, ui, viewmodel-compose |
Permission derivation
Library permissions come from two sources, merged by `deriveLibraryPermissions`:
- The AAR's packaged AndroidManifest.xml (via the binary AXML parser) — network libraries declare INTERNET themselves.
- `LIBRARY_PERMISSION_RULES`, group-based autos: `io.coil-kt`, `com.github.bumptech.glide`, `com.squareup.okhttp(3)`, `com.squareup.retrofit2`, `com.squareup.picasso`, `io.ktor` → INTERNET.
Offline behavior
- `vesk-native install` is fully offline — libraries.json is trusted as authored; it's exactly what the build compiles against.
- `vesk-native add` falls back to the pinned registry record when Maven is unreachable (with a warning).
- `vesk-native verify` reports unreachable registries as skip/warn, but hard-fails on `not-found` and `version-missing` (CI-safe).
Workflows
| Task | Command |
|---|---|
| Install a registry library | vesk-native add coil |
| Pin an exact version | vesk-native add lottie@6.5.2 |
| Use an arbitrary Maven artifact | vesk-native add com.google.code.gson:gson |
| Materialize pinned libraries (after scaffold) | vesk-native install |
| Update everything | vesk-native update |
| Update one library | vesk-native update okhttp |
| Remove a library | vesk-native remove lottie |
| Check all coordinates resolve | vesk-native verify |
Registry signatures are never guessed — every `.vsklib` field comes from real AAR/JAR metadata, Kotlin @Metadata, GitHub sources, or the runtime. A wrong signature is worse than a missing one; unknowns fail closed.