Open-Source Wikis

/

Kotlin

/

Kotlin

/

Architecture

JetBrains/kotlin

Architecture

The Kotlin compiler converts Kotlin source files into bytecode for one of four target platforms: the JVM, JavaScript, WebAssembly, or a native binary via LLVM. The pipeline is roughly: parse → frontend resolve → IR construction → IR lowering → backend code generation. The repository ships two frontends (K1 and K2/FIR) that share the same backend IR, so the JVM/JS/Wasm/Native backends are largely frontend-agnostic.

High-level pipeline

graph LR
    Source[".kt sources"] --> Lexer["Lexer + Parser<br/>(compiler/psi)"]
    Lexer --> PSI["PSI tree<br/>(KtFile, KtClass, ...)"]
    PSI --> K1["K1 frontend<br/>compiler/frontend"]
    PSI --> RawFir["Raw FIR builder<br/>compiler/fir/raw-fir"]
    RawFir --> FIR["FIR resolution phases<br/>compiler/fir/resolve"]
    K1 --> Psi2Ir["psi2ir<br/>compiler/ir/ir.psi2ir"]
    FIR --> Fir2Ir["fir2ir<br/>compiler/fir/fir2ir"]
    Psi2Ir --> IR["Backend IR<br/>compiler/ir/ir.tree"]
    Fir2Ir --> IR
    IR --> JVM["JVM backend<br/>compiler/ir/backend.jvm"]
    IR --> JS["JS backend<br/>compiler/ir/backend.js"]
    IR --> Wasm["Wasm backend<br/>compiler/ir/backend.wasm"]
    IR --> Native["Native backend<br/>kotlin-native/backend.native"]
    JVM --> Class[".class files"]
    JS --> JsOut[".js / .mjs"]
    Wasm --> WasmOut[".wasm"]
    Native --> Bin["native binary<br/>(via LLVM)"]

Top-level directory map

Top-level dir Role
compiler/ Compiler core: PSI, K1 frontend, FIR (K2), IR, JVM/JS/Wasm backends, CLI
core/ Descriptors, deserialization, metadata, names, language settings
analysis/ Analysis API — the IDE-facing query API on top of FIR
libraries/stdlib/ The Kotlin standard library (common, JVM, JS, Native, Wasm)
libraries/reflect/ kotlin-reflect — full reflection on the JVM
libraries/scripting/ The Kotlin scripting host and definitions
libraries/tools/ Gradle plugin, Maven plugin, build-tools-api, daemon, etc.
libraries/kotlin.test/ The kotlin-test framework
libraries/kotlinx-metadata/ Reading and writing Kotlin class metadata
js/ JavaScript-specific frontend, AST, translator, npm tooling
wasm/ WebAssembly-specific frontend, IR, tests
native/ Cross-cutting Native infrastructure (commonizer, swift export, tests)
kotlin-native/ LLVM-based Native backend, runtime in C/C++, build tools
plugins/ Compiler plugins (Compose, serialization, kapt, parcelize, lombok, etc.)
jps/ IntelliJ JPS build-system integration
idea/ A small set of IDE-related glue (most IDE code lives in intellij-community)
generators/ Code generators for FIR diagnostics, IR tree, descriptors, etc.
prepare/ Distribution assembly for kotlinc, embeddable compilers, dist zips
repo/ Build-system source: included builds, gradle build conventions, test infra
tests/ Top-level test entry points and shared test infrastructure
dependencies/ Vendored third-party dependencies and bootstrap
docs/ Project documentation: contributing, FIR design notes, klib spec, etc.
spec-docs/ Specification snippets and examples
benchmarks/ Performance benchmarks

The two frontends

The repository deliberately maintains both frontends because the rollout from K1 to K2 happened over several Kotlin versions and the IDE plugin ships both for a long compatibility window.

Frontend Path Status Representation
K1 / FE 1.0 compiler/frontend/ (with compiler/frontend.common, compiler/frontend.java, compiler/resolution) Legacy, still used by older toolchains and the FE1.0 Analysis API PSI + BindingContext + descriptors (core/descriptors)
K2 / FIR compiler/fir/ Default since Kotlin 2.0 FIR (Frontend Intermediate Representation)

K2 is the strategic frontend. It works in resolution phases (see compiler/fir/resolve and FirResolvePhase.kt), with the invariant that within a phase B, all FIR elements visible to the phase are already resolved through phase A.

Both frontends emit the same backend IR, via compiler/ir/ir.psi2ir/ (K1) or compiler/fir/fir2ir/ (K2). See compiler/index.md for the full pipeline.

Backend IR and lowering

Backend IR is defined in compiler/ir/ir.tree/ and forms a uniform representation that every backend lowers to its target. The shared lowering infrastructure lives in compiler/ir/backend.common/. Each backend then adds its own platform-specific lowerings and code-generation passes:

  • compiler/ir/backend.jvm/ — emits JVM bytecode via ASM (asm package)
  • compiler/ir/backend.js/ — emits JavaScript ASTs in js/js.ast, then printed as .js / .mjs
  • compiler/ir/backend.wasm/ — emits a Wasm IR in wasm/wasm.ir, then to .wasm modules
  • kotlin-native/backend.native/ (and native/) — emits LLVM bitcode through the LLVM C API

Cross-platform binary libraries are stored as klibs (Kotlin libraries) — a portable serialization of IR plus metadata — defined in compiler/util-klib* and compiler/ir/serialization.common.

Analysis API

The Analysis API in analysis/ provides a stable query API over the FIR frontend for IDE tooling. The IntelliJ Kotlin plugin (in JetBrains/intellij-community) is its main consumer. Key modules:

  • analysis/analysis-api/ — the public API surface (Ka* types)
  • analysis/analysis-api-fir/ — the FIR-backed implementation
  • analysis/analysis-api-fe10/ — a legacy FE1.0 implementation kept for IDE compatibility
  • analysis/low-level-api-fir/ — incremental, on-demand FIR resolution for the IDE
  • analysis/analysis-api-standalone/ — standalone (non-IDE) entry point

Libraries and tooling

The standard library lives under libraries/stdlib/ and is multiplatform: a common/ source set with platform-specific overrides for jvm, js, native-wasm, and wasm. libraries/reflect/ adds full reflection on the JVM, and libraries/scripting/ provides the script host.

libraries/tools/kotlin-gradle-plugin/ (KGP) is the Gradle integration. Its API is in kotlin-gradle-plugin-api and the IDE-import surface in kotlin-gradle-plugin-idea. Maven and JPS integrations live alongside it. The Build Tools API (compiler/build-tools/) exposes a stable in-process compiler API to other tools.

Compiler plugins

The plugins/ directory holds compiler plugins that hook into FIR or IR (or both) to extend the language. The largest are:

  • plugins/compose/ — the Jetpack Compose plugin (@Composable transformation)
  • plugins/kotlinx-serialization/ — generates serializers from @Serializable
  • plugins/kapt/ — Kotlin Annotation Processing Tool (Java annotation processor support)
  • plugins/parcelize/ — Android Parcelable generation
  • plugins/allopen/, plugins/noarg/, plugins/sam-with-receiver/ — Spring/JPA-friendly modifiers
  • plugins/lombok/ — Lombok interop
  • plugins/atomicfu/ — atomic field updaters
  • plugins/power-assert/, plugins/assign-plugin/, plugins/js-plain-objects/

See plugins/index.md for details.

Build system

The project is built with Gradle. The root settings.gradle.kts enumerates the included builds and modules; the root build.gradle.kts configures the subproject graph. Convention plugins live in repo/gradle-build-conventions/ (reachable as included builds), and gradle/verification-metadata.xml enforces dependency hash verification.

The dependencies/ directory bootstraps the Kotlin compiler used to compile this repository (chicken-and-egg) and pins versions of intellij-core/idea-full. The Maven-based build for some libraries lives under libraries/pom.xml.

Testing

Test infrastructure has its own layer: compiler/test-infrastructure/, compiler/tests-common-new/, and per-area test runners. Many tests are generated — diagnostic test data sits in testData/ directories and the :generateTests Gradle task produces the JUnit runners. See how-to-contribute/testing.md.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Architecture – Kotlin wiki | Factory