Kotlin Compiler
Elide comes with a built-in Kotlin compiler. It is the stock
Kotlin compiler, but compiled into the Elide binary so it starts up
faster and saves time, especially with smaller projects. You can use it via elide kotlinc -- .... It is fully
compatible and drop-in ready with Kotlin 2.4.0. The elide build tool will also automatically compile Kotlin sources
based on
declarations in the elide.pkl manifest file.
Several Elide-specific options are accepted before --, alongside the standard kotlinc flags that go after it: --abi-only (header-only output, below), --incremental (with --incremental-cache-dir), --plugins and the --metro / --no-metro / --serialization / --atomicfu / --power-assert toggles, --report-used-deps, --tests, and --persistent_worker (Bazel persistent-worker mode, which Bazel passes without a -- separator). The -- separator is still required for the passthrough kotlinc options.
Examples
Compile and run a Kotlin file:
// Hello.kt
fun main() = println("Hello!") elide kotlinc -- Hello.kt && java -cp target HelloKtHello!Diagnostic roll-up
When a compile produces a large number of errors, Elide does not print every one and flood the terminal. Like errors are collapsed into a single entry with an occurrence count, only the first errors of each distinct kind are shown, and the rest is summarized:
kotlinc: Unresolved reference 'undefinedSymbol'.
In file: Big.kt:2:15
...
(and 499 more like this)
... 30 additional errors omitted (4 more distinct kinds).
Full report: /tmp/elide-diagnostics-….md
Show all errors with --max-errors=0.
531 errors.The number of distinct errors shown is controlled by --max-errors= after the
-- separator (default 20; 0 shows everything). When errors are omitted, the
full set is also written to a Markdown report under the system temporary
directory, and its path is printed.
elide kotlinc -- --max-errors=5 Big.ktBuilt-in compiler plugins
The distribution bundles a small set of JetBrains compiler plugins so you do not need to download them separately. Each is enabled with the standard-Xplugin= / -P plugin::= flags after the -- separator.
| Plugin | Plugin id | Purpose |
|---|---|---|
kotlinx.serialization | kotlinx.serialization | Serialization codegen. |
kotlin-power-assert | org.jetbrains.kotlin.powerassert | Diagnostic assertions (the legacy kotlin-power-assert id is still accepted). |
jvm-abi-gen | org.jetbrains.kotlin.jvm.abi | Emit ABI-only class files for compile avoidance. |
Emitting ABI jars
The jvm-abi-gen plugin writes a parallel directory of class files that keep
only the public surface plus inline-function bodies. Downstream consumers that
depend on this ABI directory recompile only when the public API actually
changes, which materially shrinks incremental rebuild time on large Kotlin
codebases.
elide kotlinc exposes a --emit-abi shortcut that wires the plugin
path and the required outputDir option for you:
elide kotlinc -- --emit-abi out/abi -d out/classes Lib.ktThis is equivalent to:
elide kotlinc -- \
-Xplugin=< elide-home>/resources/kotlin/< version>/lib/jvm-abi-gen.jar \
-P plugin:org.jetbrains.kotlin.jvm.abi:outputDir=out/abi \
-d out/classes Lib.ktInline-function bytecode is preserved in the ABI output (kotlinc must keep it
to inline at call sites in downstream modules); other method bodies are
stripped. Additional plugin options can be passed with the canonical kotlinc
syntax: -P plugin:org.jetbrains.kotlin.jvm.abi:. Supported keys
include removeDebugInfo, removePrivateClasses, preserveDeclarationOrder,
treatInternalAsPrivate, and removeDataClassCopyIfConstructorIsPrivate.
ABI-only header emit (mixed Kotlin + Java)
--abi-only emits just the ABI/header jar to -d, for build systems that key
dependents on the header (Bazel rules_elide ABI compile-avoidance). Unlike
--emit-abi, which runs a full compile and keeps the header alongside the
classes, --abi-only emits only the header. By default it still derives that
header from a full compile; the experimental IR body-stripping fast path (which
skips compiling method bodies) is off by default and enabled with
ELIDE_KOTLINC_ABI_STRIP=1. It is an Elide option, so it goes before the --
separator:
elide kotlinc --abi-only -- -d out/header.jar -cp deps.jar K.kt L.javaFor a mixed .kt + .java source set the header includes the Java types'
ABI as well as the Kotlin ABI. The Java ABI is produced by a header compiler
that reads only signatures (no method bodies), so a Java method-body edit leaves
the header byte-identical while a signature or constant change updates it — the
same digest-stability contract as the Kotlin ABI. A Java header-compilation
error fails the whole invocation rather than emitting a partial header. Both a
.jar and a directory -d target are supported.
Bazel persistent worker mode
elide kotlinc implements Bazel's persistent worker protocol so build systems
can amortise JVM startup and warm classloader / kotlin-compiler-embeddable
state across many compile actions. Bazel itself spawns the worker; you do not
typically invoke this mode by hand.
elide kotlinc --persistent_workerWith the flag set, the compiler reads length-delimited protobuf WorkRequest
messages from stdin, dispatches each through the embedded kotlinc, and emits a
WorkResponse on stdout. Captured kotlinc diagnostics land on
WorkResponse.output so Bazel can surface them on the offending target. The
response frame is written to the raw stdout file descriptor so the in-process
stdio redirection used to capture diagnostics cannot corrupt the on-the-wire
framing.
The worker is multiplex-safe: request_id is echoed on every response, so
Bazel may run it as a multiplex worker (--worker_multiplex, advertised via
supports-multiplex-workers) and issue concurrent WorkRequests to a single
process — they queue on stdin, are matched by request_id, and complete
correctly without interleaving or corruption. Singleplex pools
(--worker_max_instances=N) are equally supported. The bundled JetBrains
kotlinc is not thread-safe at parseArguments/exec time, so compiles run
serially within the process — multiplex consolidates onto one warm process
rather than adding intra-process compile parallelism. The same protocol is
exposed for elide javac.