Modern Quarkus Rules
Quarkus 3+ defaults: dev mode, build-time optimization, configuration, and CDI.
# CLAUDE.md — Modern Quarkus
## Version baseline
- Quarkus 3.6+ (3.15+ if you can adopt). Java 21.
- Pin Quarkus platform BOM in `pom.xml` / `quarkusPlatformVersion` in Gradle.
- Single source of truth for all Quarkus extensions — never mix versions.
## Dev mode
- `./mvnw quarkus:dev` (or `./gradlew --console=plain quarkusDev`) is the way you develop.
- Live reload on file change. The dev UI runs at `localhost:8080/q/dev-ui`.
- **Continuous testing** (press `r` in the dev console) runs tests on every save.
- Don't deploy dev mode to production. It's not optimized.
## Build-time vs runtime
- Quarkus does most work at **build time**: classpath scanning, reflection registration, dependency wiring.
- Application startup is fast because there's nothing to discover at runtime.
- Don't try to defer config to runtime if you don't need it. Build-time `@ConfigMapping` is faster and statically typed.
## Configuration
- `application.properties` (or `.yml` with the `quarkus-config-yaml` extension) for app config.
- `@ConfigProperty(name = "...")` for individual properties.
- `@ConfigMapping(prefix = "...")` for grouped, type-safe access:
```java
@ConfigMapping(prefix = "app.email")
interface EmailConfig {
String fromAddress();
@WithDefault("smtp.gmail.com") String smtpHost();
int smtpPort();
}
```
- Profiles: `%dev`, `%test`, `%prod`. Override per profile: `%prod.app.email.smtp-host=...`.
## CDI
- Quarkus uses **ArC** — a build-time CDI implementation. Most Jakarta CDI APIs work; some runtime-only patterns don't.
- `@ApplicationScoped` for singletons. `@RequestScoped` per HTTP request. `@Dependent` for shared cheap beans.
- Constructor injection via `@Inject`. Field injection works but constructor is preferred.
- Producers (`@Produces`) for third-party types you can't annotate.
## Logging
- Use `org.jboss.logging.Logger` or just SLF4J — both work via the same Quarkus logging.
- `quarkus.log.console.json=true` for structured logs in production.
- Per-package log levels: `quarkus.log.category."com.app".level=DEBUG`.
## Health
- Built-in `/q/health`, `/q/health/live`, `/q/health/ready`.
- Auto-detects DB and message-broker health via extensions. Custom checks implement `HealthCheck`.
## Don't
- Don't use reflection-heavy frameworks without Quarkus extensions. They won't work in native mode and probably won't optimize well in JVM either.
- Don't store mutable state in `@ApplicationScoped` beans without synchronization.
- Don't put config in `META-INF/microprofile-config.properties` — use `application.properties` for project consistency.
- Don't ignore the dev UI. It surfaces config, beans, endpoints, and metrics for free.
Other Jakarta EE templates
Quarkus REST (RESTEasy Reactive)
JAX-RS endpoints with RESTEasy Reactive — request validation and response models.
Quarkus + Hibernate ORM with Panache
Active-record and repository styles with Panache, Flyway migrations, transactions.
Modern Jakarta EE Rules
Jakarta EE 10+ namespace migration, modular architecture, and platform conventions.
Jakarta CDI
CDI scopes, qualifiers, producers, events, and the lifecycle to actually understand.
Jakarta Persistence (JPA)
Entities, fetch strategies, JPQL, transactions, and L2 cache discipline.