A native Compose Multiplatform code editor — no WebView, no JS bridges. Built as a ground-up Kotlin port of CodeMirror 6, the industry-standard web editor.
Live Demo · Documentation · API Reference
Compose Multiplatform doesn't ship a code editor. Your options are embedding a WebView (heavy, hard to integrate) or building from scratch. KodeMirror gives you a real Compose component with the full feature set of CodeMirror 6:
- Syntax highlighting for 20+ languages, plus 100+ via legacy modes
- Vim mode with 600+ ported upstream tests
- Search/replace, autocompletion, linting, code folding
- Collaborative editing and side-by-side diff/merge
- Themes — One Dark, Dracula, GitHub Light, Material Design
- Real keyboard input pipeline — layout-aware key handling, no platform hacks
All from shared Kotlin code across every Compose target.
Try the live demo to see it in action — syntax highlighting, vim mode, autocompletion, and more, all running in the browser.
| Platform | Status |
|---|---|
| wasmJs (Browser) | Tested — automated gap tests + manual browser testing |
| JVM Desktop | Unit tests pass, visual rendering lightly tested |
| Android | Unit tests pass via CI, untested on devices |
| iOS / macOS native | Compiles, experimental |
// build.gradle.kts
kotlin {
sourceSets {
commonMain.dependencies {
implementation(platform("com.monkopedia.kodemirror:kodemirror-bom:0.1.0"))
implementation("com.monkopedia.kodemirror:view")
implementation("com.monkopedia.kodemirror:commands")
implementation("com.monkopedia.kodemirror:basic-setup")
// Pick your language(s)
implementation("com.monkopedia.kodemirror:lang-javascript")
}
}
}@Composable
fun Editor() {
val session = rememberEditorSession(
doc = "function hello() {\n return 'world';\n}",
extensions = basicSetup + javascript().extension
)
KodeMirror(session = session, modifier = Modifier.fillMaxSize())
}@Composable
fun VimEditor() {
val session = rememberEditorSession(
doc = "println(\"Hello, KodeMirror!\")",
extensions = basicSetup + kotlin().extension + vim() + oneDark
)
KodeMirror(session = session, modifier = Modifier.fillMaxSize())
}| Module | Description |
|---|---|
| state | Editor state, transactions, selections, facets |
| view | Compose UI component, decorations, key handling |
| language | Language support infrastructure, syntax highlighting |
| commands | Standard editor commands (cursor movement, delete, indent, undo/redo) |
| basic-setup | Convenience bundle combining common extensions |
| Module | Description |
|---|---|
| search | Find/replace panel, search commands |
| autocomplete | Completion popup and sources |
| lint | Diagnostic display and linting |
| collab | Collaborative editing support |
| merge | Side-by-side diff view |
| vim | Vim keybindings and modal editing |
JavaScript, TypeScript, HTML, CSS, Python, Java, Kotlin, Go, Rust, Markdown, JSON, YAML, XML, SQL, C++, PHP, and more — 20+ dedicated modules plus 100+ via legacy-modes.
One Dark, Dracula, GitHub Light, and Material Design integration.
This is v0.1.0 — the API may evolve. Known issues to be aware of:
- Single editor per window — multiple simultaneous
KodeMirrorinstances share global state (#6) - Large files — parsing is synchronous, so very large documents may lag on keystroke (#7)
- Mobile/native — Android and iOS targets compile and pass unit tests but are not battle-tested on real devices yet
See all open issues for the full list.
Contributions are welcome! Please open an issue to discuss before submitting large changes.
Copyright 2026 Jason Monk
Licensed under the Apache License, Version 2.0
Originally based on CodeMirror 6 by Marijn Haverbeke, licensed under MIT. See NOTICE for details.