Despite KSP's advantages, when would you still be forced to use kapt, and how do you reason about that trade-off on a real project?
answer
- kapt runs any javac processor unchanged
- KSP needs a SymbolProcessor port
- Forced to kapt = no KSP artifact
- Scope kapt to the one holdout dependency
- One kapt processor => stub generation stays
basics
~10 sYou must keep kapt when a library only provides an old Java-style annotation processor and no KSP version. kapt works with those because it runs the standard Java processing pipeline; KSP can't run them.
solid answer
~40 skapt's one durable advantage is **broad processor compatibility**: it runs any standard `javax.annotation.processing` (javac) processor unchanged, because it generates Java stubs and uses the Java APT pipeline. KSP only runs processors written against its own `SymbolProcessor` API. So you're forced onto kapt when a **required library ships only a javac processor** with no KSP artifact (legacy or unmaintained libraries are common cases). Reasoning on a real project: keep kapt **scoped to just that dependency**, migrate everything else to KSP to shrink the stub-generation cost, and track upstream KSP support. Accept that as long as one kapt processor remains, the kapt plugin and its stub round-trip stay in the build. Weigh whether to fork/replace the library, vendor a KSP alternative, or simply tolerate the slower path versus the migration cost.
go deeper
Knows kapt is sometimes still needed for older libraries that don't support KSP.
Explains kapt runs standard javac processors unmodified while KSP needs a ported processor.
Scopes kapt to the holdout dependency, weighs replace/fork/tolerate, and knows one kapt processor keeps stub generation alive.
Drives an organization-wide strategy: tracks ecosystem KSP readiness, prioritizes replacing kapt-only deps ahead of a KMP move, and quantifies build-time trade-offs.
## kapt's lasting edge: compatibility KSP is faster and multiplatform, but kapt has **one thing it does better: it runs the entire universe of existing javac annotation processors as-is.** Because kapt generates **Java stubs** and feeds them to the standard **`javax.annotation.processing`** pipeline inside **javac**, any processor ever written for Java 'just works' through kapt. KSP requires the processor to be **re-implemented against `SymbolProcessor`/`SymbolProcessorProvider`**. No KSP artifact ⇒ KSP can't run it. ## When you're forced to keep kapt - A **required library provides only a javac processor** and has not shipped a KSP version. - A library is **unmaintained / legacy** and never will. - An internal/in-house processor was written against the Java APT API and hasn't been ported. In all these cases, KSP is simply not an option for that dependency. ## Reasoning about the trade-off ```kotlin dependencies { // Migrated to KSP — fast path ksp("androidx.room:room-compiler:<v>") // Stuck on kapt — no KSP processor available kapt("com.legacy:old-processor:<v>") } ``` Decision factors: 1. **Scope kapt narrowly.** Migrate every KSP-capable processor; leave kapt only for the holdout. You still pay for stub generation, but you minimize how much work flows through it. 2. **Cost of removal vs. tolerance.** Is the build-time penalty meaningful at your scale? If the slow processor is small, tolerating kapt may beat the cost of replacing the library. 3. **Replace / fork / vendor.** For a critical hot path, consider swapping to a library with a KSP processor, or porting the processor. 4. **Track upstream.** Watch for the library shipping KSP support so you can finish the migration and delete kapt — which finally removes stub generation entirely. 5. **Multiplatform pressure.** If you intend to go KMP, a kapt-only dependency is a hard blocker for non-JVM targets, raising the priority of replacing it. ## Bottom line Use kapt when — and only when — a needed processor has no KSP implementation. Treat it as a contained, temporary cost: maximize KSP coverage elsewhere, and plan the exit when upstream KSP support lands or you replace the library.
- If only one legacy library needs kapt, what's the cost to the rest of the build?The kapt plugin and its stub-generation pass remain active, so the whole module still pays the stub round-trip even though other processors run on KSP.
- What makes a kapt-only dependency especially costly for a future KMP move?kapt is JVM-only, so a kapt-only library can't generate code for Native/JS targets at all, turning it into a hard blocker rather than just a slowdown.
saying these in an interview costs you the question
- Claiming KSP can run any javac processor
- Saying there's never a reason to keep kapt
- Not realizing one kapt processor keeps stub generation
- Ignoring fork/replace/vendor as options
- Treating kapt removal as free regardless of library support