The Rest of the Story: May Edition - JVM Weekly vol. 178
KotlinConf devoured the calendar this month, so, exceptionally, Kotlin gets first billing in a dedicated section - and then it’s back to the usual.
KotlinConf ate the calendar this month, so Kotlin gets first fiddle in a dedicated Section 0 - and then the usual: Valhalla and Leyden keep grinding, the race to make the JVM the host of AI continues, and a JVM written in Go is here to make sure we don’t get too full of ourselves.
You already know the ROTS rules: this is where everything that didn’t earn its own edition lands before it rots (heh) on my backlog. But May was different. KotlinConf ‘26 happened in Munich and pulled half of the month’s news into its gravity well - the 2.4 line, context parameters, the security policy, the VS Code extension, and the by-now-inevitable “what is Kotlin doing about AI” conversation.
So this time I’m doing something I’ve never done: Section 0, devoted exclusively to KotlinConf and the broader Kotlin world. Everything else slots in behind it, grouped by theme rather than by the order it happened to hit my feed. Let’s go.
0. KotlinConf 2026 - and all things Kotlin
KotlinConf 2026 took place May 20–22 in Munich and marked 15 years of Kotlin - and the way the whole event was framed says a lot. This was a “Kotlin is now load-bearing enterprise infrastructure, please treat it accordingly” kind of conference (pretty please). The keynote highlights read less like a language pitch and more like a maturity declaration - and they’re worth splitting into a few buckets. I’ll go through them in order of how much they’ll actually change your week.
Context parameters are the headliner - and the community is already arguing about them
The flagship language feature in the 2.4 line is context parameters - the long-awaited successor to experimental context receivers and the thing JetBrains has been quietly de-mining since the PSI work in 2.3.20 (which we covered in the March ROTS). In 2.4.0-RC they’re still hidden behind the -Xcontext-parameters flag, but the conference messaging positions the 2.4 line as the one in which they stabilize. There’s also a nice ergonomic touch in the anonymous-context syntax context(_: Type), which lets you inject a dependency without naming the parameter when you only need it to satisfy the compiler.
What’s really interesting, though, is what the r/Kotlin discussion pulled out: people are reading context parameters as the foundation for capability-based architecture, where the compiler treats a type as a statically-tracked capability - you can’t call a function that requires a database handle context unless you can prove you have one, in the style of Scala 3’s capture checking. Compiler-enforced side effects: lovely in theory. But a loud part of the senior crowd pushed back on the “Can-Do” naming convention that usually rides along with it (CanAccessCache, CanWriteAudit) - arguing that this is just dependency injection dressed up as a verb, and that a plain noun interface CacheReader says the same thing with less ceremony. I land somewhere in the middle - the capability framing is real and useful at module boundaries, but if your whole codebase turns into a thesaurus of CanDoX interfaces, you’ve reinvented constructor injection with extra steps. We’ll see which way the idiom goes.
Kotlin 2.4.0-RC: the boring-but-load-bearing stuff.
Beyond context parameters, 2.4.0-RC is the release where the transition to K2 finally burns the bridges: K2 is mandatory, and the old JVM backend is gone entirely. The toolchain now targets JVM bytecode up to version 26, Kotlin/Native GC pause times dropped by ~15% thanks to concurrent marking, and stdlib got primitive overloads for StringBuilder.insert to kill some boxing overhead. One thing to flag in red: the 2.4 stdlib contracts are incompatible with the 2.3 compiler (KT-85948) - that’s a hard break, so don’t mix it in a multi-module build and don’t expect it to go smoothly. PowerAssert’s ABI also stabilized, and the Compose compiler now skips group generation for inline lambdas that don’t contain @Composable calls. Details in What’s new in Kotlin 2.4.0-RC.
Koog 1.0: a stable foundation for agents in Kotlin.
The other big keynote announcement was Vadim Briliantov - Koog’s tech lead and author - shipping the stable Koog 1.0, JetBrains’ open-source framework for building AI agents in Kotlin and Java, running on backend, mobile, KMP, and even in the browser. It’s JetBrains’ centerpiece in the “who builds the production-grade agentic platform” race — and the concrete materialization of the eval-driven-development thesis as an honest answer to LLM non-determinism.
The 1.0 isn’t just a number. Modules now split into stable and beta streams so production code can pin to APIs that won’t break without a deprecation cycle; every previously @Deprecated API is gone (event handlers, pipeline, agent/strategy/DSL, tools, persistence, MCP, Spring autoconfig, RAG - a proper sweep), and the graph DSL node names are finalized. On the technical side: a redesigned Java interop layer, HTTP transport decoupled from Ktor, OpenTelemetry for Kotlin Multiplatform (Langfuse, Weave, and DataDog now run on every Koog target via a Ktor-based OTLP/JSON exporter, not just JVM), and Anthropic prompt caching out of the box.
Add integrations with Spring AI and Ktor, persistence and recovery for long-running agents, and intelligent history compression. Maven Central: ai.koog:koog-agents:1.0.0. If you’re building agents on the JVM and don’t want to drag in a Python stack, this is now the most serious “idiomatic Kotlin all the way down” candidate.
Kotlin/Wasm goes Stable.
From the same RC, but worth its own line: Kotlin/Wasm reached Stable status. After years of “promising but experimental,” Wasm is now a full-fledged target you can lean on. Combined with the broader Wasm-on-JVM momentum (more in Section 1), the “browser as a deployment target” story for Kotlin stops being aspirational.
Maturity in security: JetBrains becomes a CVE Numbering Authority
This is the announcement nobody live-tweeted but the one your compliance team will care about most. JetBrains rolled out a formal security support policy for kotlin-stdlib and kotlin-reflect, and crucially - registered as a CVE Numbering Authority (CNA). That means JetBrains now issues its own CVE identifiers and manages vulnerability disclosure with the same rigor you’d expect from Oracle or Red Hat. The policy guarantees patches for the three most recent minor versions (currently 2.1.x, 2.0.x, 1.9.x), commits to strict binary and source compatibility for those patches, and allows out-of-band hotfixes for critical issues. For anyone deploying Kotlin in finance, healthcare, or anything that ships with an auditor attached, this is the “Kotlin has grown up” paperwork you’ve been waiting for.
KMP: Swift interop without the Objective-C tax, and a real docs portal
The big Kotlin Multiplatform story is direct Swift export - bypassing the Objective-C header bridge, which according to JetBrains yields smaller binaries and lower call-site overhead on iOS. If you’ve ever stared at a mangled Obj-C interop signature wondering where your nice Kotlin API went - this is the fix. Alongside that, JetBrains consolidated the scattered KMP guides into a single learning portal aligned with the Kotlin 2.0.0+ era, covering modern expect/actual patterns, source-set configuration in the Gradle Kotlin DSL, the current Native memory model, Ktor, and SQLDelight. Less “version soup,” more single source of truth. Overdue and welcome.
Backend tooling grows up: Exposed 1.0, kotlinx-rpc, and Spring leaning in
On the server side, the conference finally shipped Exposed 1.0 - API stability for JetBrains’ SQL framework after what feels like a decade of “well, it’s basically stable already.” It comes with: experimental kotlinx-rpc (a pure-Kotlin alternative to gRPC) and native Vector types tuned for similarity search for AI workloads. The Spring alignment also continues - Josh Long was on the ground reinforcing “Kotlin-first” in the evolution of Spring Boot’s API, which remains one of the more significant partnerships for day-to-day JVM productivity. A related release this month is Ktor 3.5.0, keeping the networking layer current.
Kotlin meets AI - and JetBrains wants your data on it
JetBrains pulled two parallel threads here. The first is research: a strategic initiative to close the AI gap between Java and Kotlin, targeting four workflows - completion, chat, autonomous agents, and code review. The honest premise underneath is that LLMs trained on a mountain of Java tend to produce Kotlin with a Java accent - losing DSLs, sealed classes, conciseness - and JetBrains wants to fix this through context injection and Kotlin-specific tuning rather than hoping foundation models figure it out on their own.
The accompanying Kotlin-AI-a2 survey gets at the points of greatest friction: KMP structures, complex coroutine orchestration, and type-safe DSL construction, with an explicit emphasis on improving the K2 compiler’s metadata export so an in-IDE assistant gets real semantic context. If you have an opinion on where AI mangles your Kotlin (you do), this is the survey to fill out.
The second thread is plumbing: kotlin-agent-skills, a framework that exposes the compiler’s own understanding to agents over the Model Context Protocol - search_symbols for semantic indexing, find_usages for the code graph, plus Gradle hooks to actually run compile and run_tests. The pitch is right: stop letting the model guess, and let it correct itself based on real compiler feedback. This is the same “agents grounded in deterministic tooling” thesis JetBrains has been hammering on all year, now aimed squarely at Kotlin. (And yes - this is the repo where the AGP 9.0 migration skill from last month lives, so it’s being actively populated.)
VS Code extension - in alpha, with caveats
JetBrains officially shipped a first-party “Kotlin by JetBrains” VS Code extension in alpha, built on the kotlin-lsp backend. The strategic read is clear: be where the developers are - in lightweight, polyglot editors where IntelliJ isn’t always the default. The realistic read, per the community thread, is more tempered - Neovim users on the same LSP report lag and finicky completion, and KMP support is immature enough to be a dealbreaker for production work. The recurring architectural note also resurfaces: that the old Gradle jvm plugin is becoming a burden and new projects should default to multiplatform. JetBrains frames this explicitly as a “thin” experience for quick edits, not a play for parity - IntelliJ remains the only full-feature option. Good first step; manage expectations.
And for dessert: Gamebit
To close Section 0 with something that isn’t a roadmap slide - JetBrains spotlighted Gamebit by Dmytro Kurets , a board-game AI project that deliberately doesn’t reach for an LLM.
It’s classic algorithmic AI - Monte Carlo Tree Search, Minimax with alpha-beta pruning - implemented in Kotlin with a bitboard representation that packs entire game states into 64-bit primitives to keep GC pressure near zero during deep tree traversals, plus compile-time-enforced legal-move generation, all targeting KMP. In a year where every “AI” headline assumes a transformer, this is a genuinely refreshing reminder that in constrained, heavily logical domains, well-tuned deterministic search eats neural networks for breakfast. Star it for the bit-twiddling alone.
That’s it for Kotlin. Now - the rest of the story.
1. May: The Rest of the Story
Last month I got a little misty over Project Metropolis going to Call For Votes. May delivered the sequel. OpenJDK is moving to deprecate and remove JVMCI - the Java-Level JVM Compiler Interface from JEP 243 that let Graal slot into HotSpot as a C2 replacement via -XX:+EnableJVMCI. Same logic as Metropolis: maintaining a stable interface for an external compiler while HotSpot’s internals churn became unsustainable once the strategic future of Graal as a standalone, vendor-distributed product was settled. Native Image is untouched, but Truffle languages and projects like TornadoVM now have a hard dependency on specific GraalVM builds. If you read the Metropolis section in April and thought “well, that’s the end of Graal in mainline” - this is the formal full stop. A genuinely bold experiment, quietly retired.
Two JDK Reviewer nominations worth noting, both signaling where OpenJDK is allocating its review bandwidth. Casper Norrbin from Oracle’s HotSpot runtime team (45 contributions - a custom red-black tree, string-table optimizations, removal of StatSampler/PerfData) is positioned as a key reviewer for Valhalla‘s integration into mainline, which makes sense given how deep those changes reach into value-type memory layout. Separately, Artur Barashev from Oracle’s Java Security Libraries team (40+ contributions to sun.security.ssl, notably the TLS Certificate Compression work per RFC 8879) was nominated for the security stack - sponsored by veteran Weijun Wang. Both go through the standard Three-Vote Consensus.
I admit a small bias in amplifying that some “Artur” is being promoted. Solidarity.
Two smaller governance items close the topic. A proposal on core-libs-dev wants to resurrect a 2011 idea and allow method references as annotation element values (JLS §9.6.1) - which would let frameworks like Spring or JUnit replace brittle, runtime-validated String literals with compile-time-checked MyClass::myMethod. A nice step in the ecosystem’s long “de-Stringification.” There’s also a JEP draft to deprecate the java.sql.rowset module for removal - ~60 commits since 2017, high maintenance cost - which triggered the predictable “but I use CachedRowSet in tests” pushback. The eternal struggle between trimming the JDK and the niche tools people quietly rely on.
The race to make the JVM an AI host is sasily the most crowded topic of the month. The strategic signal: JDK 27 planning named generative AI as one of its main pillars, with talk of tuning the runtime for vector cognitive-computing patterns and high-throughput LLM orchestration - a deliberate “Java wants to be a full AI host, not just a deployment target for Python” declaration.
The proof-of-concept layer is filling in fast. Qxotic.ai uses Project Panama (JEP 454, FFM API) to talk to native inference engines like ONNX Runtime and llama.cpp directly - no JNI glue - and combines that with GraalVM Native Image for sub-100ms startup, building the case for local LLM execution on the JVM with type-safe model orchestration.
There are also two “redesign the architecture for LLMs” projects I’m bundling together because they’re the same idea from opposite ends: Carrier is an AI-first backend compiler that turns natural-language or JSON specs into idiomatic Spring Boot 3.x (Spring Data JPA, entities, controllers, synced migrations), while Aifei by James Zhan of JFinal goes the other way - a deliberately minimalist framework of 3,333 lines and zero dependencies that collapses Controller/Service/Repository/Mapper into a single “Just Service” specifically to raise “attention density” and keep the entire LLM context window aimed at business logic. Seniors will (rightly) shudder at the abandonment of separation of concerns, but both are honest attempts at designing for how agents actually reason. I’m skeptical and curious in roughly equal measure.
JetBrains continuing its “let’s turn everything into an agent” campaign, shipped an agent skill for debugging flaky tests that orchestrates the actual JVM debugger and test runner across iterations to hunt race conditions and environment leaks - agentic workflows grounded in real execution state, not static guessing. This plugs directly into their 2026 “dual-workflow” roadmap, which leans on IntelliJ’s existing static analysis engine as a real-time verification layer against LLM hallucinations, plus a local-first approach to privacy. The Codex hackathon finalists showed where the practical wins are: AST-aware context pruning to cut token waste and hallucinations, LSP-based validation of generated code, and reasoning-trace sidebars so the agent’s logic is auditable. The recurring lesson across all of this is the same one I keep coming back to in the book - the value isn’t the model, it’s the deterministic harness you wrap around it.
And as an antidote to all the optimism: Markus Eisele Spiderweb Model for quantifying Java modernization. Instead of counting lines of code, it scores six axes - Scope, Semantics, Knowledge Opacity, Integration/Data, Feedback Friction, Governance - and his sharpest insight is that it’s Knowledge Opacity (undocumented “tribal knowledge” debt) and Feedback Friction (slow, brittle CI/CD) that actually sink AI-assisted migrations. LLMs translate syntax beautifully; they won’t conjure up missing test coverage or solve an architectural constraint nobody wrote down. Required reality check for anyone selling “just point an agent at the monolith.”
The JVM is finally good at scripting, and Haoyi Li overview breaks down the three-way race: Java shedding ceremony through JEP 330, 463, and 477 (single-file execution, unnamed classes, implicit imports); Kotlin’s .kts with @file:DependsOn; and Scala CLI, arguably leading on DX thanks to using directives plus GraalVM Native Image killing the 100-200ms startup tax. Mill 0.12 wires it into tooling. The choice is now genuinely a trade-off question, not a “is this even possible” one.
On Wasm, a good landscape survey on r/java: TeaVM (WasmGC) and CheerpJ for compiling to Wasm, GraalWasm and the pure-Java Chicory for running Wasm inside a JVM as sandboxed plugins. The missing piece remains a standardized Component Model - serialization overhead at the JVM/Wasm boundary is still costly - and the community sees Project Babylon and Leyden as precursors to any official integration. Pair this with Kotlin/Wasm going Stable (Section 0) and this year’s Wasm story suddenly has legs.
A few more, rapid-fire: Scala SIP-80 proposes a Swift-style target-typed companion shorthand (.Member) and immediately triggered the “feature fatigue / freeze the language and fix 3.6.x stability first” debate that’s worth reading as a snapshot of current Scala mood.
Netflix open-sourced Nebula ArchRules, a Gradle plugin that scales ArchUnit by decoupling rules from the test lifecycle and running them as tasks bound to check, with three-tier (error/warning/info) granularity.
The IntelliJ Platform is pushing plugin authors toward a Remote-Development-ready split (headless backend vs. JetBrains client UI, ClientSession API, EDT discipline), while the fun community library swing-fluid-swipe uses JNI into AppKit’s NSEvent to bring smooth trackpad gestures to Swing on macOS.
And a benchmark of 4 million AWS Lambda invocations confirms that SnapStart pulls Java 21 cold starts down from a brutal 1,200–4,500ms to 400–600ms (at 512MB+) - effectively neutralizing Go’s and Python’s edge, although Rust’s sub-50ms still reigns. SnapStart is now a genuine alternative to Native Image if you want to keep standard JVM ergonomics in serverless.
And to close the section on a human note: the community is worried about preserving the Java Developer Journal and Dr. Dobb’s archives from the early-2000s J2SE 5.0 era, because Sys-con Media never maintained accessible digital copies. Former JDJ editor Joseph Ottinger confirmed that the physical magazines may be the only surviving record.
There’s something on point about an ecosystem so obsessed with backwards compatibility realizing that its own written history is rotting. If you have a box of those issues in the attic - scan them.
2. Release Radar
Micronaut 5.0.0 GA
Micronaut 5.0.0 went GA - the first major in three years, and deliberately a stabilization release rather than a feature dump. The center of gravity is a unified Platform BOM that syncs every module to kill version drift - which matters enormously for reproducible AOT compilation on GraalVM - on a JDK 17 base.
On the Core side, 5.0 adds a programmatic Retry and Circuit Breaker API going beyond the declarative annotations, fixes native-image initialization for “loom-carrier” threads in GraalVM 25, and ships a new Async HTTP Client. Two breaking changes worth catching: the YAML media type moves to application/yaml, and BeanIntrospectionModule is gone - read the migration guide before jumping from 4.x.
WildFly 40 GA
WildFly 40 went GA on May 21 (Brian Stansberry), and it’s a more significant release than the round number suggests.
The headline: the standard distribution moves to Jakarta EE 11 - after incubating in a Preview variant since WildFly 32, EE 11 finally hits the default server, so you get Jakarta Data backed by Hibernate Data Repositories, Jakarta Persistence 3.2 improvements, and virtual threads in Jakarta Concurrency services on Java SE 21+.
For those not yet ready to migrate, a temporary WildFly EE 10 variant appeared, and on the security front - a long-requested HashiCorp Vault integration feature pack. This ties in nicely with the Jakarta EE 12 thread from Section 1: the spec keeps moving, and the servers are just now shipping the previous edition.
Payara → Azul Payara Community
Payara Platform Community is becoming Azul Payara Community, moving under Azul governance and aligning its lifecycle with Azul Zulu OpenJDK and Java LTS support windows. Community builds remain TCK-compliant with Jakarta EE, but expect changes to distribution binaries and artifact naming that will trickle into your dependency management and CI. More predictable long-term support in exchange for watching how the vendor model handles transparency.
Quarkus 3.35.0
Quarkus 3.35.0 shipped JAR tree-shaking, native PGO, and @Transactional support for Hibernate Reactive - but the most interesting bit is the integration with IBM Semeru / OpenJ9 Shared Classes Cache. It’s a pragmatic middle path to faster cold starts via -Xshareclasses and multi-stage Docker builds that shift JIT warmup from runtime to build time, with a nice RSS reduction because instances share cached metadata - no closed-world constraints and full reflection retained.
And as a fun stress test of the model: Quarkus Insights #246 walks through redesigning Minecraft server infrastructure as cloud-native (GraalVM native images, Mutiny, reactive messaging) to avoid stop-the-world GC pauses. Full notes.
Hibernate ORM 7.4.0
Hibernate ORM 7.4.0 is more than a routine bump - it ships an incubating but potentially substantial StateManagement SPI along with two annotations built on top of it: @Temporal for mapping temporal data and querying by “effectivity” over time (an effectivity-columns table or a split between current and historical data, transparent to client code) and @Audited for tracking modifications in a separate audit log.
There’s also a migration guide worth reviewing - among other things, on Oracle the HQL current date/local date expressions now translate via trunc(). If you’ve ever rolled your own temporality or Envers-based audit - take a look before you add another custom one.
Apache Fory 1.0.0
Apache Fory 1.0.0 - the high-performance multilingual serialization framework (you’ll remember it as Fury) hits 1.0, and in this case it’s a real milestone: from this version on, binary compatibility is guaranteed, and the unified xlang type system becomes the default mode across all languages (compatible-mode reads, simplified field ordering, better list/array compatibility).
decimal and bfloat16 support for xlang join in, and on the JVM side: Kotlin gets xlang, KSP, and IDL schema support, while Java gets Android serialization and annotation processor support. 84 PRs from 11 contributors. For anyone who’s measured serialization cost on a hot path, worth benchmarking against Protobuf or your current setup.
JUnit 6.1.0
JUnit 6.1.0 continues the 6.x line with a few genuinely useful items. The most interesting for large suites: a new WorkerThreadPoolHierarchicalTestExecutorService for parallel execution backed by a plain thread pool instead of ForkJoinPool, plus an experimental memory-cleanup mode (junit.platform.execution.memory.cleanup.enabled) useful for massive test counts.
There’s also the ability to redirect XML events from OpenTestReportGeneratingListener to a socket instead of a file. If you’re tracking the JUnit 6 migration (Keycloak’s new test framework targets it, for one) - keep this on the radar.
JobRunr 8.6.0
JobRunr 8.6.0 - the background jobs library that increasingly doubles as infrastructure for agentic stacks (recall ClawRunr built on top of it). 8.6.0 adds full JDK 26 compatibility, official Quarkus 3.33 LTS support, performance improvements for recurring jobs and SQL table validation, and - practically useful for agentic patterns - the ability to set a timeout for jobs waiting for an external signal, so they don’t hang indefinitely.
LangChain4j 1.14.0
LangChain4j 1.14.0 - the workhorse of the JVM AI stack keeps iterating. Beyond bug fixes and dependency bumps, there’s a new IMMEDIATE_IF_LAST attribute in the ReturnBehavior enum (returns the result of the AI service execution loop when a given tool is the last one in the LLM’s response) and an OpenAiOfficialResponsesChatModel class, closing the pair with its streaming counterpart for OpenAI’s Responses API.
A line in which the “resilient, stateful agents as baseline” trend is still visible.
Apache NetBeans 30
NetBeans 30 is out - the IDE that quietly keeps shipping solid, on-time releases for the part of the community that never left it. Details in the changelog, but if you’re in the NetBeans camp, this is a standard “upgrade and move on.”
JReleaser 1.24.0 / Ujorm 3.0.0 / Bob v0.7.0
Three smaller items: JReleaser 1.24.0 for release automation adds Zernio to the announcer list and a reproducible flag to enforce reproducible output; Ujorm 3.0.0, a lightweight ORM, hits major; and Bob v0.7.0 is a lightweight builder generator for Java for those allergic to annotation processors.
3. GitHub All-Stars
Four community projects that aren’t formal releases but are too interesting to lose.
Jacobin - a JVM written in Go
Jacobin is exactly the type of project that keeps me humble: a full reimplementation of the JVM in Go, targeting the Java 21 spec - and it’s not a toy. It handles invokedynamic, CONSTANT_Dynamic, sealed classes, and records via its own class-file parser, runs modern class files without a local JDK, and delegates memory management to Go’s GC instead of building its own heap.
It’s a strict interpreter with no JIT, so it won’t threaten HotSpot on throughput - but as a clean-room, OpenJDK-independent execution engine, it’s a genuinely valuable lens on how the JVM instruction set actually works. The kind of repo I’ll be pointing people at when they want to understand class loading rather than just trust it.
Strange - pure-Java quantum simulation
Strange by Johan Vos is a pure-Java API for quantum computation and a state-vector simulator - qubits and gates (Hadamard, Pauli-X, CNOT) via a declarative DSL for circuit construction, no native dependencies, no QPU access.
Originally a teaching tool for the Manning book Quantum Computing in Action, now maturing under RedFX, it lets you prototype Grover or Shor algorithms entirely inside a standard JVM. Classical state-vector simulation obviously doesn’t scale to real quantum hardware, but as an on-ramp for Java developers to experiment with quantum logic before committing to cloud QPUs, it lowers the barrier to entry considerably.
Versionparser - zero-dependency, multi-scheme version parsing
Versionparser is the unglamorous-but-essential kind of utility: a Java 17+ library, zero dependencies, that parses, compares, and normalizes version strings across incompatible ecosystems - SemVer 2.0.0, Maven, Python (PEP 440), Debian, RPM, OpenJDK formats, plus CalVer, caret/tilde ranges, epochs, and pre-release identifiers. If you’ve ever hand-rolled version-comparison logic and watched it die on a Debian version with an epoch prefix, you know exactly why a unified Version interface with no transitive dependencies is worth bookmarking - perfect for dependency scanners and build-system tooling.
Benetto - private on-device transcription on Android
Benetto (1.0.0, MIT) is a Kotlin Android app that runs whisper.cpp locally for voice transcription in 99+ languages - zero outbound network traffic, zero API cost. It uses the Whisper “Small” model (~466MB - an obvious disk-space hurdle), cleanly separates the AudioRecord-based recording module from the inference engine, and persists everything through Room.
As a reference for wiring high-performance C++ inference into Kotlin/Android internals, and as a response to data sovereignty concerns around cloud transcription APIs, it’s a tidy demonstration of where on-device ML has arrived.
PS: Fresh off KotlinConf ‘26 in Munich as a media partner - I wasn’t there myself, but the representation was solid - thanks to Grzegorz Król for the running updates. Hence this fairly Kotlin-centric edition; no regrets.


















