quarkusio/quarkus
> Java framework that moves framework startup work to build time — fast-booting, low-memory services on the JVM or as GraalVM native binaries.
GitHub repo · Official website · License: Apache-2.0
Overview
Quarkus is a Java framework started at Red Hat and first released in 2019 ("Supersonic Subatomic Java")[^1]. Its founding bet: traditional Java frameworks (Spring, Jakarta EE servers) do enormous work at startup — classpath scanning, annotation processing, proxy generation, dependency-injection wiring — that is repeated identically on every boot. Quarkus performs that work once, at build time, baking the results into bytecode. The payoff is startup in tens of milliseconds (native) or well under a second (JVM) and a much smaller heap, which matters in containers, Kubernetes autoscaling, and serverless.
The same build-time metadata makes Quarkus the most practical on-ramp to GraalVM native-image: extensions register reflection, resources, and proxies so that closed-world native compilation works without the manual configuration that sinks most naive attempts. Quarkus stays standards-adjacent — Jakarta REST, CDI, JPA via Hibernate, MicroProfile — so the programming model reads like familiar enterprise Java, even though the machinery underneath is not.
The tradeoff is that the build-time model only works for libraries wrapped as Quarkus extensions. Inside the (large) extension ecosystem, things are cohesive; outside it, arbitrary Java libraries mostly work in JVM mode but can fail in native mode until someone writes the metadata. In December 2024 Red Hat announced Quarkus would move to the Commonhaus Foundation for vendor-neutral governance, while Red Hat remains the dominant contributor[^2].
Getting Started
# Quarkus CLI (via SDKMAN, Homebrew, or JBang); Maven/Gradle plugins also work
quarkus create app org.acme:getting-started
cd getting-started
quarkus dev # live-reload dev mode with Dev UI at /q/dev-ui
// src/main/java/org/acme/GreetingResource.java — Quarkus REST (Jakarta REST)
package org.acme;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello from Quarkus REST";
}
}
./mvnw package # fast-jar for the JVM
./mvnw package -Dnative # GraalVM/Mandrel native executable
Architecture / How It Works
Every Quarkus extension is split into two artifacts:
1. Deployment module — runs only at build time. Build steps consume and produce build items (annotation indexes via Jandex, config, generated classes) in a dependency-ordered graph. Code that must run at application start is written as recorders: invocations are captured at build time and replayed as generated bytecode (via the Gizmo library) at runtime[^3]. 2. Runtime module — the only part shipped in the application. No classpath scanning, no reflective annotation lookup at boot.
ArC is Quarkus's build-time CDI implementation. Beans are discovered, validated, and wired during the build; unused beans are removed. It implements CDI Lite rather than the full specification — portable extensions (javax.enterprise.inject.spi.Extension) don't run, which is a real compatibility gap when porting Jakarta EE code.
The HTTP and I/O core is Eclipse Vert.x on Netty. Quarkus REST (formerly RESTEasy Reactive) executes handlers on the event loop by default and dispatches to worker threads when a method signature or @Blocking indicates blocking work. Mutiny is the house reactive-types library (Uni/Multi), and since Quarkus 3.x virtual threads (@RunOnVirtualThread) offer a third concurrency option on modern JVMs. Three models in one framework is flexibility, but also a recurring source of "why is my endpoint pinning the event loop" bugs.
Native compilation uses GraalVM native-image or Mandrel, Red Hat's supported downstream distribution. Dev mode adds Dev Services (auto-started Testcontainers databases/brokers when no config is present), continuous testing, and live reload backed by a multi-classloader setup that differs from the production flat classpath — occasionally the source of dev/prod divergence.
Production Notes
JVM vs native is a real decision, not a checkbox. Native gives ~10-100x faster startup and lower RSS, but typically lower peak throughput than a warmed JIT-compiled JVM, no dynamic agent attachment, and harder profiling. The usual guidance: native for scale-to-zero, CLIs, and memory-constrained pods; JVM mode for sustained-throughput services. Many teams ship JVM mode plus AppCDS and never need native.
Native builds are expensive. Minutes of build time and multiple GB of RAM per build are normal; CI runners need sizing for it. Test coverage must include @QuarkusIntegrationTest runs against the actual native binary — JVM-mode tests do not prove native works, because reflection or resource lookups missing from the metadata fail only at native runtime.
Build-time vs runtime config split. A subset of application.properties keys is fixed at build time (extension wiring, datasource kind, etc.). Overriding them with environment variables at deploy time does not take effect — a classic footgun when one image is promoted across environments. Check the config reference for the lock icon before assuming a property is runtime-tunable.
Upgrades. Quarkus releases fast (minor about every month) and designates an LTS stream roughly every six months (3.2, 3.8, 3.15, 3.20, ...)[^4]. The 2.x to 3.0 jump carried the javax to jakarta namespace migration plus Hibernate ORM 6; the quarkus update command applies OpenRewrite recipes and handles most of it, but bespoke code and third-party libraries lag. Non-LTS minors can change extension defaults; read the migration guide per release.
Ecosystem edges. If a dependency lacks an extension (check the Quarkiverse Hub, the community extension org), JVM mode usually works but native mode needs hand-written reflect-config.json or @RegisterForReflection. Spring compatibility layers (quarkus-spring-*) cover common annotations, not the Spring runtime — treat them as a porting aid, not a migration guarantee.
When to Use / When Not
Use when:
- Kubernetes/serverless Java where startup latency and memory-per-pod are the cost drivers (scale-to-zero, Knative, high pod density).
- You want GraalVM native images without owning reflection metadata yourself.
- Your stack fits the extension catalog (REST, Hibernate/Panache, Kafka, gRPC, Camel, LangChain4j) and you value the dev-mode loop.
- Greenfield services where standards-flavored Java (Jakarta REST, CDI, JPA) is the team's home turf.
Avoid when:
- You depend heavily on Spring's ecosystem (Security, Batch, Cloud, countless starters) — porting costs usually exceed the footprint savings.
- Long-running, throughput-bound monoliths on big heaps: a warmed JVM erases most of Quarkus's headline advantage, and Spring Boot's ecosystem is deeper.
- Your critical dependencies are dynamic/reflection-heavy with no extension — you will fight native metadata indefinitely.
- You need full CDI (portable extensions) or classic Jakarta EE server semantics — ArC is deliberately a subset.
Alternatives
- spring-projects/spring-boot — use instead when ecosystem breadth and hiring pool outweigh footprint; Spring's own AOT/native support has narrowed the gap.
- micronaut-projects/micronaut-core — the closest architectural sibling (compile-time DI via annotation processors); pick it for a lighter framework less tied to one vendor's product line.
- helidon-io/helidon — Oracle's counterpart; Helidon SE with virtual threads when you want a minimal, no-DI, no-magic server.
- eclipse-vertx/vert.x — drop a level down: the toolkit Quarkus builds on, for teams that want explicit event-loop control without framework opinions.
- ktorio/ktor — JVM services in idiomatic Kotlin with coroutines instead of a Java-first stack.
History
| Version | Date | Notes | |---------|------|-------| | 0.x | 2019-03 | Public launch as "Supersonic Subatomic Java"[^1]. | | 1.0.0 | 2019-11-25 | First stable release[^5]. | | 2.0.0 | 2021-06-30 | Vert.x 4, continuous testing, Dev Services, Quarkus CLI. | | 3.0.0 | 2023-04-26 | Jakarta EE 10 (jakarta.* namespace), Hibernate ORM 6, Dev UI rewrite. | | 3.2 | 2023-07-05 | First designated LTS stream[^4]. | | 3.8 / 3.15 / 3.20 | 2024-02 / 2024-09 / 2025-03 | Subsequent LTS streams (~6-month cadence). | | 3.38 | 2026-07 | Current release train (3.38.0.CR1, 2026-07-15). |
Repo signals (fetched 2026-07-18): ~15.8k stars, ~3.2k forks, ~2.8k open issues/PRs, pushed same day — a high-velocity, corporate-backed monorepo where the issue count reflects the hundreds of extensions it hosts, not abandonment.
References
[^1]: Quarkus launch coverage, Red Hat, 2019-03. https://quarkus.io/about/ [^2]: "Quarkus is moving to the Commonhaus Foundation", Quarkus blog, 2024-12. https://quarkus.io/blog/quarkus-moving-to-commonhaus/ [^3]: Quarkus documentation, "Writing extensions" (build steps, build items, bytecode recorders). https://quarkus.io/guides/writing-extensions [^4]: Quarkus blog, "Long-Term Support (LTS) releases". https://quarkus.io/blog/lts-releases/ [^5]: quarkusio/quarkus release 1.0.0.Final, 2019-11-25. https://github.com/quarkusio/quarkus/releases/tag/1.0.0.Final
Tags
java, kubernetes, cloud-native, microservices, graalvm, native-image, web-framework, reactive, dependency-injection, build-time-optimization