Konvoy is a native-first Kotlin build tool focused on making Kotlin/Native compilation as easy, fast, and painless as Cargo.
Konvoy avoids Gradle/Maven-style complexity by providing:
- A small, Cargo-like CLI (
konvoy build/test/run) - A tiny declarative manifest (
konvoy.toml) - Deterministic builds via
konvoy.lock - Fast rebuilds via a content-addressed cache
- Predictable output locations under
.konvoy/
Scope note: Konvoy is native-first. JVM builds are intentionally out of scope.
- Status
- Supported platforms
- Requirements
- Quick start
- Project layout
- Commands
- Output contract
- Design goals
- Dependencies
- Testing
- Managed toolchains
- Linting
- Editor support
- Development
Early-stage prototype / design-driven build. Expect rapid iteration and breaking changes.
- Linux — x86_64 and ARM64
- macOS — x86_64 (Intel) and ARM64 (Apple Silicon)
- No manual Kotlin/Java installation needed. Konvoy automatically downloads and manages the Kotlin/Native compiler and a bundled JRE.
- Platform toolchain installed for your host OS:
- macOS: Xcode Command Line Tools (
xcode-select --install) - Linux: GCC/build-essential (
sudo apt install build-essentialon Debian/Ubuntu)
- macOS: Xcode Command Line Tools (
konvoy init --name hello
cd hello
konvoy build
konvoy run
Konvoy projects use:
konvoy.toml— project manifest (name, kind, toolchain, dependencies)konvoy.lock— pinned toolchain versions and dependency hashes.konvoy/— build outputs + cache
Example:
hello/
konvoy.toml
konvoy.lock
src/
main.kt
.konvoy/
build/
cache/
konvoy init [--name <name>] [--lib]— create a new binary or library projectkonvoy build [--target <triple|host>] [--release] [--verbose] [--force] [--locked]— compile the projectkonvoy run [--target <triple|host>] [--release] [--force] [--locked] [-- <args…>]— build and runkonvoy test [--target <triple|host>] [--release] [--verbose] [--force] [--locked] [--filter <pattern>]— build and run testskonvoy lint [--verbose] [--config <path>] [--locked]— run detekt static analysis on Kotlin sourceskonvoy update— resolve Maven dependencies (including transitives via POM) and updatekonvoy.lockkonvoy clean— remove build artifactskonvoy doctor— check environment, toolchain, and dependency setupkonvoy toolchain install [<version>]— install a Kotlin/Native versionkonvoy toolchain list— list installed toolchain versions
Konvoy writes artifacts to stable paths:
- Binary debug:
.konvoy/build/<target>/debug/<name> - Binary release:
.konvoy/build/<target>/release/<name> - Library debug:
.konvoy/build/<target>/debug/<name>.klib - Library release:
.konvoy/build/<target>/release/<name>.klib
- No build DSL: config is declarative; behavior is predictable.
- Reproducible by default: lockfile + toolchain fingerprint.
- Fast inner loop: content-addressed caching keyed by source+toolchain+target.
- Actionable errors: missing toolchain/SDK issues should be one-line fixes.
- Native-first: targets are real OS/arch outputs, not JVM bytecode.
Konvoy is implemented in Rust as a Cargo workspace.
cargo build # build all crates
cargo test # run all tests
cargo run -- build # run konvoy with a subcommand
cargo test -p konvoy-config # run tests for a single crate
cargo clippy --workspace # lint all crates
cargo fmt --all # format all crates
CI runs check, test (Linux + macOS), clippy, and rustfmt on every push and PR to main.
See docs/code-style.md for coding conventions.
Konvoy supports two kinds of dependencies: path dependencies (local projects) and Maven dependencies (external libraries from Maven Central).
Depend on other Konvoy projects via relative paths:
[dependencies]
my-utils = { path = "../my-utils" }Library projects are created with konvoy init --lib and produce .klib files. The generated project uses src/lib.kt as its entrypoint (instead of src/main.kt for binaries):
my-utils/
konvoy.toml
src/
lib.kt
Depend on external Kotlin/Native libraries from Maven Central using direct Maven coordinates:
[package]
name = "my-app"
[toolchain]
kotlin = "2.1.0"
[dependencies]
kotlinx-coroutines = { maven = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version = "1.8.0" }
kotlinx-datetime = { maven = "org.jetbrains.kotlinx:kotlinx-datetime", version = "0.6.0" }
my-utils = { path = "../my-utils" }The maven field is a standard Maven coordinate (groupId:artifactId). The version field pins the exact version to use.
Each dependency must have exactly one source type — either path or maven + version — not both.
After adding or changing a Maven dependency, run konvoy update to resolve and lock:
konvoy update # resolve deps, fetch POMs, write hashes to konvoy.lock
konvoy build # downloads only the klib needed for your host target
konvoy update performs these steps:
- Reads
[dependencies]fromkonvoy.toml - Fetches artifact metadata (
.moduleJSON first, POM XML as fallback) from Maven Central - Resolves transitive dependencies via BFS with cycle detection
- Detects version conflicts (suggests pinning an explicit version in
konvoy.toml) - Downloads the per-target
.klibfor each supported platform and computes SHA-256 hashes (also discovers cinterop klibs from.modulemetadata) - Writes the full dependency set to
konvoy.lockwithrequired_byfor transitive deps
At build time (konvoy build), only the klib for your current host target is needed. Subsequent builds reuse cached artifacts from ~/.konvoy/cache/maven/.
konvoy.lock pins the exact version and per-target SHA-256 hash for every Maven dependency (direct and transitive). Transitive dependencies include a required-by field tracing the dependency chain back to konvoy.toml:
[[dependencies]]
name = "kotlinx-coroutines"
source_type = "maven"
version = "1.8.0"
maven = "org.jetbrains.kotlinx:kotlinx-coroutines-core"
source_hash = "..."
[dependencies.targets]
linux_x64 = "sha256:..."
macos_arm64 = "sha256:..."Transitive dependencies are tracked automatically with a required_by field listing which direct dependency pulled them in.
Use --locked on build/test/run to error if the lockfile is out of date instead of silently updating.
Konvoy supports compiler plugins via the [plugins] section. Plugins use Maven coordinates — any Kotlin/Native compiler plugin JAR on Maven Central can be used:
[plugins]
serialization = { maven = "org.jetbrains.kotlin:kotlin-serialization-compiler-plugin", version = "{kotlin}" }The {kotlin} placeholder resolves to the Kotlin version set in [toolchain]. Runtime libraries needed by the plugin (e.g., kotlinx-serialization-core, kotlinx-serialization-json) should be added as regular Maven dependencies in [dependencies]:
[dependencies]
kotlinx-serialization-core = { maven = "org.jetbrains.kotlinx:kotlinx-serialization-core", version = "1.7.3" }
kotlinx-serialization-json = { maven = "org.jetbrains.kotlinx:kotlinx-serialization-json", version = "1.7.3" }Konvoy has a built-in test framework using kotlin.test. Test sources live in src/test/ and are compiled alongside your project sources using konanc's -generate-test-runner flag.
Create test files under src/test/:
hello/
src/
main.kt
test/
math_test.kt
Tests use standard kotlin.test annotations:
import kotlin.test.Test
import kotlin.test.assertEquals
class MathTest {
@Test
fun addition() {
assertEquals(4, 2 + 2)
}
}konvoy test
Filter tests by name pattern:
konvoy test --filter "MathTest.*"
The --filter flag is forwarded to the test runner as --ktest_filter.
Test builds are cached separately from regular builds (using a debug-test / release-test profile key), so running konvoy test won't invalidate your normal build cache.
Konvoy automatically downloads and manages Kotlin/Native toolchains. The first konvoy build (or konvoy toolchain install) downloads the compiler and a bundled JRE to ~/.konvoy/toolchains/<version>/. No manual Kotlin or Java installation is required.
Konvoy integrates detekt for Kotlin static analysis. Enable it by adding detekt to [toolchain] in konvoy.toml:
[package]
name = "my-app"
[toolchain]
kotlin = "2.1.0"
detekt = "1.23.7"The detekt-cli JAR is automatically downloaded to ~/.konvoy/tools/detekt/<version>/ on first use and its SHA-256 hash is pinned in konvoy.lock.
Detekt runs using the JRE bundled with the managed Kotlin/Native toolchain, so no separate Java installation is needed.
To customize detekt rules, place a detekt.yml file in the project root or pass --config <path>:
konvoy lint # run with defaults or detekt.yml
konvoy lint --config my-rules.yml # use custom config
konvoy lint --verbose # show raw detekt output
Install Konvoy for VS Code from the Marketplace, or search "Konvoy" in the Extensions panel.
- Commands — Build, Run, Test, Lint, Clean, Doctor, Update, and Toolchain management via
Ctrl+Shift+P - Title bar buttons — Build (dropdown), Run (debug/release toggle), Test, Lint, Clean, Update, and Doctor in the editor title bar for
.ktfiles,konvoy.toml, andkonvoy.lock konvoy.tomlsupport — Syntax highlighting, validation on save, autocomplete, and hover docs- Diagnostics — Build errors and detekt findings in the Problems panel
- Tasks — Auto-detected konvoy tasks via
Ctrl+Shift+B
See the extension README for full details.
Install Konvoy for IntelliJ from the JetBrains Marketplace, or search for "Konvoy" in Settings → Plugins → Marketplace.
The plugin provides full Kotlin/Native language intelligence by teaching IntelliJ how to read konvoy.toml. Once installed, IntelliJ's built-in Kotlin plugin handles completion, navigation, refactoring, and diagnostics automatically.
Features:
- Project sync — Parses
konvoy.tomlandkonvoy.lockto configure modules, source roots, klib dependencies, and Kotlin/Native target platform - Auto re-sync — Watches
konvoy.tomlandkonvoy.lockfor changes - Run configurations — Build, Run, Test, and Lint via the standard run menu
- Toolchain SDK — Discovers managed toolchains from
~/.konvoy/toolchains/ - Full Kotlin intelligence — Completion, go-to-definition, find usages, rename, diagnostics, and refactoring (provided by IntelliJ's Kotlin plugin)
Install from source:
cd editors/intellij
./gradlew buildPluginThe plugin zip will be at build/distributions/konvoy-intellij-<version>.zip. Install it in IntelliJ via Settings → Plugins → ⚙️ → Install Plugin from Disk... and select the zip file.
Requirements: IntelliJ IDEA 2024.2+ (Community or Ultimate) with the Kotlin plugin installed.
See the plugin README for full details.
