migrate-spring-to-quarkus
Migrates Spring Boot applications to Quarkus using a modular, gate-driven approach. Supports Spring compatibility extensions and native Quarkus migration paths. Use when the user wants to migrate, convert, or port a Spring Boot app to Quarkus, mentions "spring to quarkus", "quarkus migration", "replace spring", or asks about migrating "pom.xml", "build.gradle", "Spring MVC", "Spring Data JPA", "Thymeleaf", "@SpringBootApplication".
Skill body
Spring Boot to Quarkus Migration
Modular, gate-driven migration of Spring Boot applications to Quarkus.
Critical Rules
- Never delete code you cannot migrate. If you cannot fully migrate a piece of code, leave the original in place with a
// TODO: Migration required — <reason>comment explaining what needs to change and why. This applies to:- Methods, classes, or annotations you don’t know how to convert
- Spring-specific patterns without a clear Quarkus equivalent
- Configuration or wiring code whose purpose is unclear
If you must remove code (e.g., a Spring-only base class), document what was removed and why in a
// REMOVED:comment at the same location.
- Don’t break the build. Run the compile command after each phase (
./mvnw clean compile -DskipTestsfor Maven,./gradlew clean compileJava -x testfor Gradle). Never move to the next phase with a broken build. - Document every decision. When choosing between migration approaches, explain the trade-off to the user.
- No silent changes. Every file modification must be intentional and traceable. If a check fails after a phase, diagnose and fix — don’t skip the check or delete the failing code.
Reference Files
Load the relevant reference file when working on a module:
| Reference | Use during |
|---|---|
| references/dependency-map.md | Build module: dependency and plugin mapping |
| references/annotation-map.md | Code module: annotation, DI, REST, Data, Security migration |
| references/config-map.md | Build module: configuration property migration |
Step 1: Analyze & Choose Strategy
Scan the application to understand what needs to migrate:
- Build system: Read the build file (
pom.xmlfor Maven,build.gradleorbuild.gradle.ktsfor Gradle) — Spring Boot version, starters, plugins - Java code: Search for Spring annotations (DI, REST, Data, Security, Scheduling)
- Configuration: Read
application.properties/application.yml, check for profiles - UI / View layer: Check for Thymeleaf/JSP templates, static resources, Model+View patterns
- Tests: Check for
@SpringBootTest,@WebMvcTest,@DataJpaTest
Present a summary table with area, findings, and complexity. Then ask the user to choose a strategy:
- Spring compatibility (recommended): Use
quarkus-spring-web,quarkus-spring-data-jpa, etc. Minimal code changes. - Native Quarkus: Replace all Spring annotations with JAX-RS/CDI. More work, full Quarkus experience.
Stop here and wait for the user’s response before continuing. Do not ask about git workflow or anything else in the same message.
Step 2: Git branch (optional)
After the user has chosen a strategy, check if the target project is a git repository. If it is, propose the git workflow:
Migration workflow: Each migration run can be isolated in its own branch (
migration/run-01,migration/run-02, …) created frommain. The branch will contain a single commit with all changes plus a migration report. A draft PR againstmainwill be created for review — it is never merged, it serves as a permanent diff and discussion record. Would you like to use this workflow?
- User accepts → follow modules/git.md — Pre-migration section. Propose the branch name and wait for confirmation before creating it.
- User declines → skip git management entirely, proceed with migration in the current branch.
- Not a git repo → inform the user, skip git management, proceed normally.
Step 3: Execute Modules
Decision Gate Table
For each module, evaluate whether it applies to this project. A module executes only when its gate is PASS. Inspect the project to determine the gate result — do not rely on blind grep commands; use your understanding of the codebase.
| Module | Gate Check | Gate Result |
|---|---|---|
| jdk | JDK 21+ required | ALWAYS – stop migration if < 21 |
| build | Spring Boot parent/starters/spring-boot-maven-plugin in pom.xml, or Spring Boot/io.spring.dependency-management plugins in build.gradle(.kts) |
PASS if Spring Boot build markers found; SKIP otherwise |
| code | Spring annotations in Java sources (@Component, @Service, @Controller, @Repository, @Entity, @Autowired, etc.) |
PASS if Spring annotations found; SKIP otherwise |
| frontend | Thymeleaf/JSP templates in templates/ or static resources in static/ |
PASS if view layer found; SKIP otherwise |
| testing | Spring test annotations in test sources (@SpringBootTest, @WebMvcTest, @MockBean) |
PASS if Spring tests found; SKIP otherwise |
| cleanup | Leftover Spring artifacts after all other modules | ALWAYS — runs after all other modules |
Execution Protocol
FOR module IN [build, code, frontend, testing, cleanup]:
1. EVALUATE — inspect the project for the gate condition
2. DECIDE
IF gate == ALWAYS → proceed to step 3
IF gate == PASS → proceed to step 3
IF gate == SKIP → log "Module {name}: SKIPPED — {reason}", mark checkbox, continue
3. LOAD — read the module file and relevant reference files
4. EXECUTE — follow the module instructions, adapting to the chosen strategy
5. COMPILE — run the project's compile command (`./mvnw clean compile -DskipTests` for Maven, `./gradlew clean compileJava -x test` for Gradle)
Fails → diagnose and fix before proceeding
6. LOG — mark checkbox as done
Running Individual Modules
To run a single module outside the full migration flow, read its file directly:
- “Read
modules/build.mdand execute it” - “Run only the frontend module”
- “Re-run the cleanup module”
The module will use the current project state and the chosen strategy (if already decided). If no strategy has been chosen, the module will ask.
Step 4: Verify the Migration
Run each check in order. A check fails = stop and fix before continuing.
| # | Check | Command (Maven / Gradle) | Pass criteria |
|---|---|---|---|
| 1 | Builds | ./mvnw clean package -DskipTests / ./gradlew clean build -x test |
Exit code 0, no compilation errors |
| 2 | No Spring deps | Search build file for org.springframework |
Zero Spring deps (except Spring compat extensions if using that strategy) |
| 3 | Has Quarkus | Search build file for io.quarkus |
Quarkus BOM and at least one extension present |
| 4 | Tests pass | ./mvnw test / ./gradlew test |
All tests pass using @QuarkusTest |
| 5 | Starts up | ./mvnw quarkus:dev / ./gradlew quarkusDev |
App starts, curl http://localhost:8080/q/health returns UP |
| 6 | No leftover templates | Search for Thymeleaf/JSP references | None remaining (unless intentionally kept) |
Step 5: Migration Review (Self-Reflection)
Answer each question honestly:
- What migrated cleanly? Patterns that mapped 1:1.
- What required manual judgment? Non-obvious decisions made.
- What was left as TODO? Every
// TODO: Migration requiredcomment and why. - Was any code removed? What, where, justification. Flag runtime risks.
- What checks failed initially? Failures from Step 4 and how you fixed them.
- What’s missing from the skill references? Mappings you had to figure out.
Migration Report
Present the review as a structured report:
## Migration Report: [app-name]
### Summary
- Strategy: [Full Migration / Spring Compatibility]
- Agent: [AI agent name - e.g claude, pi, opencode, gemini, etc]
- Model: [model name — e.g. claude-sonnet-4-6, check system context]
- Modules completed: [X/4]
- Checks passed: [X/6]
- Token usage: [input tokens / output tokens — check session stats]
- Estimated cost: [~$X.XX — token counts × per-model pricing from anthropic.com/pricing]
### Changes by Module
| Module | Files changed | Key changes |
|--------|--------------|-------------|
| build | pom.xml or build.gradle(.kts), application.properties | ... |
| code | ... | ... |
| frontend | ... | ... |
| testing | ... | ... |
### Validation Results
| Check | Result | Notes |
|-------|--------|-------|
| Builds | PASS/FAIL | |
| No Spring deps | PASS/FAIL | |
| Has Quarkus | PASS/FAIL | |
| Tests pass | PASS/FAIL | |
| Starts up | PASS/FAIL | |
| No leftover templates | PASS/FAIL | |
### Unmigrated Code (TODOs)
| File | Line | What | Why not migrated |
|------|------|------|-----------------|
### Removed Code
| File | What was removed | Justification |
|------|-----------------|---------------|
### Skill Improvement Suggestions
- [Any missing mappings, unclear instructions, or edge cases discovered]
Step 6: Commit and PR (only if git workflow was accepted)
Follow modules/git.md — Post-migration section. Ask the user for confirmation before committing, and again before pushing / creating the draft PR. Do not proceed with either action without explicit user approval.
Skill frontmatter
Work with this as data
Every skill here is available over the APIs.io API and to AI agents over MCP.