A lightweight, on-device IDE that edits and builds Android & Java projects — no laptop, no Gradle daemon.
CodeAssist is an extensible IDE framework that runs entirely on device (Android/ART) and edits and builds Android/Java projects without hosting Gradle. A full Gradle runtime is too heavy for a phone, so CodeAssist models projects itself, mimics Gradle's incremental task engine without the Gradle daemon, and drives the Android toolchain (aapt2, D8/R8, apksigner) directly.
It is designed to be lightweight:
- No Gradle daemon. Projects are a declarative model compiled into an incremental task DAG with fingerprint up-to-date checks and a persistent cache — Gradle's good ideas, none of its weight.
- Flat-memory indexing. Library/SDK symbol indices are disk-backed immutable segments queried in place through a bounded block cache, so heap stays flat regardless of index size.
- Fast, incremental everything. Editing one file re-runs only the affected build tasks; completion and analysis reuse a cached compilation environment instead of rebuilding it per keystroke.
- On-device toolchain. Pure-Java tools (Eclipse JDT/ecj, D8/R8, apksigner) run in process; native aapt2 is invoked as a subprocess.
It ships with a Compose Multiplatform UI and both desktop and Android launchers.
- ☕ Java code intelligence — error-tolerant parsing, ranked completion, diagnostics, and quick-fixes powered by Eclipse JDT.
- 🟪 Kotlin completion (beta) — full Kotlin code completion on device, tuned to the same ranked experience as Java. How it works →
- 🧩 Block editing — project any Java file into a Scratch-style block tree and edit it there; changes write back to the source byte-for-byte. How it works →
- 📐 Android XML assist — tag, attribute, and resource completion for layouts/manifests with live validation.
- 📦 Real APK builds on device — resolve, compile, dex, package, sign, and install — no laptop.
- 🔌 Extensible everywhere — module types, build systems, language backends, analyzers, quick-fixes, and more all plug in through extension points.
Any Java file can be projected into interlocking, typed blocks — and edited there. The block tree is a live projection of the same DOM the code editor uses, so the two views never drift; a block edit compiles to the smallest possible source edit, leaving every untouched line and comment intact.
Typed value sockets (Scratch-style shapes for boolean/number/string/type), inline completion inside sockets, palette search, and drag-and-drop all map back to the same surgical projection pipeline. Read how the projection and edit round-trip work →
CodeAssist tracks completion quality, editor latency, indexing, and build performance against committed
baselines (a regressionTest suite that fails CI on a quality regression). The numbers below regenerate
on each release.
| Area | Metric | Result |
|---|---|---|
| Java completion quality | recall / top-1 / MRR | 100% / 75% / 0.88 |
| Java completion latency (per keystroke) | member access / type ref | 4.3 ms / 2.8 ms |
| Symbol index quality | recall / top-1 / MRR | 100% / 90% / 0.95 |
| Symbol index query | prefix / fuzzy | ~4.4 µs / ~56 ns |
| Build engine (14-module Java project) | full build / incremental | ~0.30 s / 4 tasks re-run |
What the metrics mean
- recall — fraction of cases where the expected completion appears in the list at all.
- top-1 / top-5 — fraction where the expected item is ranked first / within the first five.
- MRR (mean reciprocal rank) — average of
1 / rankof the expected item;1.0means it is always first. - latency — wall-clock time to compute completion at a keystroke (recorded on the maintainer's machine, so treat as indicative; quality metrics are deterministic across machines).
- incremental tasks — how many build tasks re-run after a single-file edit; fewer means more precise incrementality.
364 tests passing across 92 suites · 0 failing · 0 skipped (framework / CI_CORE_ONLY).
The badges and the numbers in this section are regenerated automatically on each release (see
.github/workflows/update-readme.yml).
| Doc | What's in it |
|---|---|
| docs/architecture.md | Project model, the two graphs, build abstraction, concurrency model. |
| docs/modules.md | The module map and responsibilities. |
| docs/extension-points.md | Extension points and the language-backend SPI. |
| docs/language-support.md | DOM, completion, the language backends, indexing, analysis, block editing. |
| docs/kotlin-completion.md | How on-device Kotlin completion works. |
| docs/block-editing.md | How the projectional (block) editor works. |
| docs/build-system.md | The task engine, the native pipelines, Gradle compat. |
Dependencies point downward only (acyclic). Platform modules carry no domain knowledge; domain behavior is contributed through extension points.
platform-core no domain knowledge; depended on by all
└─ vfs-api
└─ project-model-api
├─ build-api
└─ language-api
deps-api / index-api / analysis-api / block-api → the layers above
ide-ui (Compose UI) ← ide-core (engine→UI bridge) ← ide-desktop, ide-android
The full table — every module, its packages, and its responsibility — is in docs/modules.md.
The build uses the Gradle wrapper and a JDK 17+ (developed against the JetBrains Runtime).
# Core framework only (pure JVM; no Android SDK or Compose shells needed)
CI_CORE_ONLY=true ./gradlew check
# Full build, including the Compose UI and Android launcher (requires the Android SDK)
./gradlew build
# Run the desktop IDE
./gradlew :ide-desktop:run
# Assemble the Android launcher
./gradlew :ide-android:assembleDebugThe regression suite (completion quality, latency, allocation, and build-at-scale) is opt-in and runs
via the regressionTest tasks against committed JSON baselines.
- IDs are
@JvmInline value classwrappers — no stringly-typed APIs. - Open-ended classifications (
NodeKind,BuildSystemId,LanguageId) are string-backed value classes so plugins can extend them; closed sets (DependencyScope,SymbolKind) are enums. - Long-running entry points are
suspendand run under the read/write-lock discipline; model and DOM access happens inside read/write actions. - Mutation is transactional: stage on a
*Transaction/Modifiable*, thencommit(). - Editor features target the neutral
DomNode/Symbol/Scope, never a backend's native types.
CodeAssist is licensed under the GNU General Public License v3.0. See LICENSE.








