rgoussu@goussu: ~/library/java/frameworks
~/library/java/frameworks cat quarkus.md

Quarkus deep dive

# Quarkus in depth — build-time augmentation, ArC CDI, RESTEasy Reactive, Panache, Mutiny, Dev Services and first-class native image.

Conceptsaved 2026-08-09 #java#frameworks#quarkus#graalvm#microprofile#reactive

Overview

Quarkus ("supersonic subatomic Java", Red Hat) is built around one idea: do at build time what other frameworks do at every startup. Classpath scanning, annotation processing, config parsing and bean-graph resolution happen during augmentation; the runtime just executes pre-computed bytecode. That yields fast JVM startup, low memory, and — because all reflection and dynamic behavior is known at build time — the smoothest GraalVM native-image path in the ecosystem, while staying standards-based (Jakarta EE core profile + MicroProfile).

Key points

  • Build-time augmentation: extensions run build steps that scan, index (Jandex) and generate bytecode once; startup work collapses to executing recorded initialization.
  • ArC: Quarkus's CDI implementation ("CDI-lite") — build-time resolved @ApplicationScoped/@Inject, unused beans removed, client proxies generated ahead of time.
  • REST: RESTEasy Reactive (quarkus-rest) implements Jakarta REST (JAX-RS) and runs blocking or reactive endpoints on the same stack, dispatching to the right thread pool.
  • Persistence: Hibernate ORM with Panache (quarkus-hibernate-orm-panache) — active-record or repository style with boilerplate stripped.
  • Mutiny: the reactive core (Uni/Multi) used across reactive extensions; Vert.x event loop underneath everything.
  • Dev mode: quarkus dev gives live reload, a Dev UI, Dev Services (auto-provisioned databases/brokers via Testcontainers) and continuous testing.
  • Native first-class: -Dnative builds via GraalVM or Mandrel (Red Hat's native-image distribution), containerized build option requiring no local GraalVM.
  • Standards: MicroProfile Config/Health/Metrics/OpenAPI/Fault-Tolerance implemented by the SmallRye project family.

Details

Augmentation and the extensions model

A Quarkus extension has a deployment module (build steps, executed at build time) and a runtime module (what ships). Build steps read the Jandex class index, resolve configuration, pre-generate serializers and proxies, and record bytecode that replays at boot. This is also how native image is tamed: the extension declares reflection/resource needs itself, so users rarely write reflect-config.json by hand. The catalog (code.quarkus.io) covers Kafka (quarkus-messaging-kafka), Redis, Keycloak/OIDC (quarkus-oidc), scheduler, gRPC, and hundreds more.

Programming model

CDI annotations (@Inject, @ApplicationScoped, @Observes) via ArC; JAX-RS annotations (@Path, @GET) via RESTEasy Reactive; config via MicroProfile @ConfigProperty or typed @ConfigMapping. ArC's build-time nature brings limits worth knowing: no runtime bean registration, portable CDI extensions unsupported (build-time extensions instead).

Reactive core

Vert.x is the engine: all I/O runs on its event loops. RESTEasy Reactive inspects method signatures — return Uni<T>/Multi<T> and you run on the event loop; return T or annotate @Blocking and you're dispatched to a worker (or virtual) thread. Mutiny was designed as a more navigable API than RxJava/Reactor (no 400-operator wall).

Developer experience

Dev mode is the flagship: code changes recompile on next request; Dev Services detect a missing datasource/broker config and silently start a Testcontainers-backed PostgreSQL, Kafka, Keycloak, etc.; continuous testing re-runs affected tests on change. @QuarkusTest boots the app once per test profile for fast integration tests.

Native image

./mvnw package -Dnative (or quarkus build --native) produces a static binary — tens of milliseconds startup, tens of MB RSS — ideal for serverless and high-density Kubernetes. Trade-off: longer builds, peak throughput typically below JIT; measure before committing. @QuarkusIntegrationTest re-runs the test suite against the built native binary.

Examples

@Path("/orders")
public class OrderResource {
  @Inject OrderService service;               // ArC, resolved at build time

  @GET
  public Uni<List<Order>> list() {            // reactive: event loop
    return Order.<Order>listAll();            // Panache active record
  }

  @POST
  @Blocking                                    // explicit worker-thread dispatch
  public Order create(OrderRequest req) { return service.place(req); }
}
quarkus dev                       # live reload + Dev Services + continuous testing
./mvnw package -Dnative -Dquarkus.native.container-build=true   # Mandrel in a container

Related