Codelens
Structural answers for JVM codebases, from bytecode instead of grep.
Fast structural lookups for a coding agent working in a JVM codebase: who implements this, who references this type, what this method calls. Answers come from compiled bytecode and the resolved Gradle classpath, not text search.
$ codelens xref com.example.PaymentProcessor
IMPLEMENTS StripeProcessor StripeProcessor.kt:14
IMPLEMENTS PaypalProcessor PaypalProcessor.kt:9
FIELD CheckoutService CheckoutService.kt:31
PARAM PaymentController PaymentController.java:58
4 references · 2 IMPLEMENTS · 1 FIELD · 1 PARAM
$ codelens calls com.example.CheckoutService#submit
→ PaymentProcessor.charge(Money)
→ OrderRepository.save(Order)
→ EventBus.publish(OrderPlaced)
Overview
Codelens analyzes JVM codebases (Java and Kotlin) by loading a project’s compiled bytecode and resolved classpath, then answering structural questions over a CLI and a small local HTTP API. It’s built for the questions text search gets wrong: who implements this interface, who references this type, what calls this method. Those answers are often clearer in the bytecode and classpath than in source text alone. And it’s built for a particular reader: a coding agent. A human usually has IntelliJ; an agent working the same repo mostly has grep. Codelens is an attempt to hand it part of the structural view the IDE would have given.
Architecturally it’s two pieces. A Kotlin/Ktor server runs in the background, scans the target with ClassGraph, resolves the classpath through the Gradle Tooling API (running the project’s own Gradle, so it tracks across Gradle and JDK versions) and serves analysis over a local REST API, shutting itself down when idle. Staying resident per project is what keeps repeat lookups fast. A single static Go binary is the CLI: it manages the server, auto-starts it on first use, and formats results. Gradle projects are the tested, supported path today. Crucially, the tool ships only general primitives; framework knowledge lives in installable skills, so the binary stays small and the agent learns the framework.
Where it stands
Codelens is an experiment in giving agents faster, more structural ways to understand JVM projects. It follows the same pattern as the other tools here: a single CLI an agent can drive, structured --json output everywhere, and domain expertise pushed into installable skills rather than hard-coded into the binary. It is promising, but I do not do enough JVM work right now to call it as proven as Roost, Prox, or Strix. Agent harnesses are also starting to ship language-server support of their own, so the open question is whether a persistent bytecode index gives agents something better.
Answers from bytecode, not text
Loads compiled bytecode and the resolved classpath, so it can answer what implements an interface, who references a type, and what calls a method: relationships source-only tooling often misses.
xref, calls, and deps
Trace everything that references a type (xref), the calls a method makes (calls), and the project dependency graph (deps): the structural facts you need most during a migration.
Framework-agnostic primitives
The binary ships general primitives only. Framework-specific analysis (like assessing a Ratpack-to-Spring-Boot migration) is composed from them in installable agent skills rather than baked into the tool.
Works with the agent you already use
One CLI any agent can drive, plus skills that install into Claude Code, GitHub Copilot, OpenCode, and others via npx skills add charliek/codelens.
Auto-managed server
A Kotlin/Ktor server scans bytecode with ClassGraph and resolves the classpath via the Gradle Tooling API, running the project's own Gradle, so it tracks across Gradle and JDK versions. It stays resident per project to keep repeat lookups fast; the Go CLI auto-starts it and it shuts down when idle.
JSON on every command
Every command supports --json, so agents and scripts get structured output to act on, while humans get readable tables.