Open-Source Wikis

/

Kotlin

/

Compiler

/

JS backend

JetBrains/kotlin

JS backend

Active contributors: Artem Kobzar, Ilya Goncharov, Zalim Bashorov

The JS backend compiles Kotlin to JavaScript. The modern path is the JS IR backend in compiler/ir/backend.js/, which lowers IR and produces JavaScript via the js/js.ast AST. The older path, js/js.translator/, generates JS directly from the K1 frontend and is in maintenance.

Purpose

Take lowered IR and produce JavaScript output: ES5/ES6 modules, UMD, plain scripts, and modern .mjs. Handle JS-specific concerns: JS interop (external declarations, dynamic type), property descriptors, this binding, prototype chains, and the absence of static typing in the host.

Directory layout

compiler/ir/backend.js/        Lowerings + driver for the JS IR backend
js/
├── js.ast/                    JS AST types (JsExpression, JsStatement, ...)
├── js.config/                 JS-specific compiler configuration
├── js.frontend/               JS-specific frontend extensions
├── js.parser/                 JS parser (used to roundtrip JS for testing)
├── js.serializer/             Klib IR ↔ serialized form for JS
├── js.sourcemap/              Source map generation
├── js.tests/                  JS test runners + .testdata
├── js.translator/             Legacy K1 → JS translator (still present)
├── npm/                       Helpers for npm tooling integration
├── typescript-export-model/   Types used by the TS-export feature
├── typescript-export-standalone/ Standalone TS-export
└── typescript-printer/        Pretty-prints TypeScript declarations

Key abstractions

Type Where Role
JsIrBackendContext compiler/ir/backend.js/... Top-level shared state for the JS IR backend.
JsIrLoweringPipeline (logical) compiler/ir/backend.js/lower/ The ordered JS-specific lowerings.
JsExpression, JsStatement js/js.ast/... The output AST of the backend.
JsAstSerializer js/js.ast/... Serializes JS AST for klib.
IrModuleDeserializer (JS variant) compiler/ir/serialization.js/ Reads JS klibs back into IR.
TypeScript export js/typescript-* Optional generation of .d.ts files.

How JS compilation works

graph LR
    IR["Lowered IR"] --> JsLower["JS lowerings<br/>backend.js/lower/"]
    JsLower --> JsAst["JS AST<br/>(js/js.ast)"]
    JsAst --> Print["JS printer"]
    Print --> Out[".js / .mjs"]
    JsLower --> Klib["serialization.js<br/>(klib IR + JS AST)"]

JS is a multi-stage backend because of its multi-module model:

  1. Each Kotlin module compiles to a klib (IR + JS AST fragments).
  2. The final binary step (production mode) links all klibs and emits a single .js (or .mjs) file. This is similar to how Native links klibs into a binary.

Output module formats

  • UMD — historical default for the JS legacy backend.
  • ES modules — modern default for the JS IR backend; output is .mjs.
  • CommonJS — supported.
  • Plain (script) — for browser <script> tags.

The output mode is selected via compiler arguments (defined in compiler/arguments/).

TypeScript export

The JS IR backend can emit .d.ts files describing the public Kotlin API. Implementation lives in js/typescript-export-model/, js/typescript-export-standalone/, and js/typescript-printer/. This is exposed via the @JsExport annotation and a compiler flag.

Source maps

js/js.sourcemap/ generates V3 source maps so that JS debuggers can step into Kotlin source. Source maps are tied to the JS IR backend's IR-to-AST translator.

npm integration

js/npm/ provides helpers for KGP's kotlin("js") Gradle target — manifest generation and lookup of JS dependencies.

Legacy path

js/js.translator/ is the original (pre-IR) JS backend. It walks K1 PSI/descriptors and emits JS directly without going through IR. It still exists for backward compatibility and tooling that has not migrated. The js.translator and js.frontend directories share helpers with the IR path — don't assume code there is dead.

Integration points

  • Input: lowered IR (or K1 PSI, in the legacy path).
  • Output: JS files, .d.ts files (optional), source maps (optional), JS klibs.
  • Used by: compiler/cli/cli-js/ (kotlinc-js), KGP's kotlin("js") and kotlin("multiplatform") targets, and the standalone JS toolchain.
  • Tested by: js/js.tests/ — runs Kotlin → JS → Node.js round-trips.

Where to start

For a new JS lowering or codegen feature, look in compiler/ir/backend.js/lower/. For JS-specific frontend work (e.g., adjusting how external is resolved), compiler/fir/fir-js/ and js/js.frontend/. JS test data lives under js/js.tests/ and compiler/testData/codegen/box/ (the same box/ tests run on every backend).

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

JS backend – Kotlin wiki | Factory