Quarkus Full-Stack Development
Expert guidance for developing full-stack Quarkus applications with integrated frontend/backend architecture.
Description
This skill provides comprehensive guidance for working with Quarkus full-stack applications, particularly those using the Quarkus Web Bundler extension for integrated frontend development. It covers project structure, development workflows, API design, and testing strategies for modern Java applications.
Instructions
When working with Quarkus full-stack projects, follow these guidelines:
1. Understand the Project Architecture
Before making changes:
Read the project's CLAUDE.md or README to understand the application's purpose and constraintsIdentify the data model and storage strategy (in-memory, database, etc.)Review the API structure in `src/main/java/` REST resource classesExamine frontend structure in `src/main/resources/web/`Note any specific design decisions like authentication strategy or messaging integration2. Backend Development (Java/Quarkus)
When working with REST APIs:
Place REST resources in packages like `com.{company}.{project}.api`Use `@Path`, `@GET`, `@POST` annotations from RESTEasy ReactiveReturn appropriate HTTP status codes (200, 201, 400, 404, etc.)Use `@Produces(MediaType.APPLICATION_JSON)` and `@Consumes(MediaType.APPLICATION_JSON)`Implement proper error handling and validationKeep business logic separate from REST resourcesUse records for immutable DTOs where appropriate (Java 17+)Storage patterns:
For in-memory storage, use thread-safe collections like `ConcurrentHashMap`For database storage, use Panache (Hibernate ORM with Quarkus)Keep data access logic in separate repository/service classes3. Frontend Development (Web Bundler)
When working with frontend code:
All frontend assets go in `src/main/resources/web/`Create JavaScript/TypeScript modules for different concerns (API client, UI components, state management)Use modern ES6+ JavaScript featuresLeverage TailwindCSS for styling if availableImplement proper error handling and user feedbackStore client state in browser localStorage when appropriateMake API calls to relative paths like `/api/questions`Web Bundler features:
Automatically bundles JavaScript, TypeScript, CSS, SCSSUses Deno and esbuild (no Node.js required)Provides live reload in dev modeOutputs bundled assets served by Quarkus4. Development Workflow
Follow this workflow for implementation:
**Step 1: Plan**
Review requirements and existing codeIdentify data models neededDesign API endpointsSketch frontend components**Step 2: Backend First**
Implement data models (POJOs, records, entities)Create storage/repository layerBuild REST API endpointsWrite unit tests for APIs**Step 3: Frontend**
Create API client module for backend communicationBuild UI componentsImplement user interactions and state managementAdd styling and polish**Step 4: Integration Testing**
Test complete user flowsVerify error handlingCheck edge casesValidate data consistency**Step 5: Polish**
Add loading states and user feedbackImprove error messagesOptimize performanceReview accessibility5. Testing Strategy
Write comprehensive tests:
Use `@QuarkusTest` annotation for integration testsUse RestAssured for API testingTest both success and error casesVerify data state changesMock external dependencies if neededRun tests frequently: `./mvnw test`6. Common Commands
Use these Maven/Quarkus commands:
**Development:**
```bash
./mvnw quarkus:dev # Start dev mode with live reload
./mvnw test # Run all tests
./mvnw quarkus:test # Continuous testing mode
```
**Building:**
```bash
./mvnw package # Create runnable JAR
./mvnw package -Pnative # Create native executable
```
**Running:**
```bash
java -jar target/quarkus-app/quarkus-run.jar
```
7. Code Organization Best Practices
Structure your code logically:
`api/` - REST resource classes`model/` - Data models, POJOs, records`service/` - Business logic`repository/` - Data access layer`dto/` - Data transfer objects`web/` (in resources) - Frontend code organized by feature8. Key Constraints to Respect
Always honor project-specific constraints:
If specified "in-memory only", don't add database dependenciesIf "simple auth", don't implement complex security frameworksIf "event-optimized", prioritize fast startup and low footprintFollow the technology stack defined in project documentationRespect the implementation roadmap and feature priorities9. Error Handling
Implement robust error handling:
Return appropriate HTTP status codesProvide clear error messages to frontendLog errors appropriatelyHandle validation failures gracefullyShow user-friendly error messages in UI10. Live Reload and Iteration
Leverage Quarkus dev mode:
Keep `./mvnw quarkus:dev` running during developmentMake changes to Java or frontend codeBrowser auto-refreshes on changesFast iteration without manual restartsExamples
Example 1: Creating a REST API Endpoint
```java
@Path("/api/questions")
@Produces(MediaType.APPLICATION_JSON)
public class QuestionResource {
@Inject
QuestionService questionService;
@GET
public List<Question> getQuestions() {
return questionService.getAllQuestions();
}
@POST
@Path("/answers")
@Consumes(MediaType.APPLICATION_JSON)
public Response submitAnswer(AnswerSubmission submission) {
boolean correct = questionService.validateAnswer(submission);
return Response.ok(Map.of("correct", correct)).build();
}
}
```
Example 2: Frontend API Client
```javascript
// web/js/api-client.js
export async function fetchQuestions() {
const response = await fetch('/api/questions');
if (!response.ok) throw new Error('Failed to fetch questions');
return response.json();
}
export async function submitAnswer(username, questionId, answer) {
const response = await fetch('/api/answers', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, questionId, answer })
});
if (!response.ok) throw new Error('Failed to submit answer');
return response.json();
}
```
Important Notes
**Single Application**: Frontend and backend are served from one Quarkus application**No Node.js Required**: Web Bundler uses Deno and esbuild internally**Live Reload**: Works for both Java and frontend code changes**In-Memory Trade-offs**: If using in-memory storage, data resets on restart**Extension Management**: Use `./mvnw quarkus:add-extension -Dextensions="extension-name"` to add Quarkus extensions**Configuration**: Application properties go in `src/main/resources/application.properties`Constraints
Always read existing project documentation (CLAUDE.md, README, roadmap files) before making changesDon't add dependencies or complexity beyond project requirementsRespect architectural decisions like storage strategy and authentication approachFollow the implementation roadmap if one existsTest thoroughly before considering a feature completeMaintain consistency with existing code style and patterns