What should a CLAUDE.md for Spring Boot include?
A CLAUDE.md for Spring Boot should give Claude Code the wrapper commands to run, test and verify the app, show where the main application class and feature packages live, and state your rules for dependency injection, configuration, secrets and tests. Keep it under 200 lines, as Anthropic's memory docs recommend, and include the gotchas that only your team knows.
Spring Boot is a good case for a CLAUDE.md because the framework changed a lot in version 4 and models have seen years of older code. The Spring Boot 4.0 migration guide lists changes such as Jackson 3 as the default JSON library, a renamed web starter and the removal of @MockBean. Without a few lines that pin the version, Claude can write code that compiles against Spring Boot 3 and fails against 4.
The template targets Spring Boot 4.1, which the system requirements page says needs at least Java 17 and Spring Framework 7. It uses Maven, with Gradle equivalents in the adaptation section. Choices such as feature packages, DTO records and Testcontainers are common conventions, not requirements, so swap them for yours. For the file format itself, see what a CLAUDE.md file is.
The Spring Boot CLAUDE.md template
Save this as CLAUDE.md at the root of the repository, replace the angle-bracket placeholders, and delete lines that do not apply.
# <App name>
<One sentence: what this service does and who calls it.>
Stack: Spring Boot 4.1, Java <21>, Maven (wrapper), Spring MVC, Spring Data JPA,
<PostgreSQL>, JUnit 6, Testcontainers.
## Commands
- Run: `./mvnw spring-boot:run`
- Run with dev containers from the test classpath: `./mvnw spring-boot:test-run`
- All tests: `./mvnw test`. One class: `./mvnw test -Dtest=OrderServiceTest`
- Full build and checks: `./mvnw verify`
- Package: `./mvnw package`, then `java -jar target/<app>-0.0.1-SNAPSHOT.jar`
- Format: `<your formatter command>`
- Done means: `./mvnw verify` passes with no new warnings
## Project structure
- Main class: `src/main/java/com/<company>/<app>/Application.java`, in the root package
- Feature packages under the root: `order/`, `customer/`, each with its
controller, service, repository and entities
- `src/main/resources/application.yaml`: shared config.
`application-<profile>.yaml`: per-profile overrides
- `src/test/java/`: mirrors the main packages. `TestApplication.java`: dev launcher
with Testcontainers
- `compose.yaml`: local services, started by spring-boot-docker-compose
## Spring rules
- Constructor injection with `final` fields. No `@Autowired` on fields
- Group settings in `@ConfigurationProperties` records, not scattered `@Value`
- Controllers return DTO records, never JPA entities
- One `@RestControllerAdvice` maps exceptions to HTTP responses
- Transactions go on service methods, not controllers
- Spring Boot 4: use `spring-boot-starter-webmvc` and Jackson 3 (`tools.jackson.*`
packages; annotations stay in `com.fasterxml.jackson.annotation`)
- Jakarta EE APIs (servlet, persistence, validation) come from `jakarta.*`, not `javax.*`
## Testing
- Controller tests: `@WebMvcTest(OrderController.class)` with `MockMvcTester`
- Repository tests: `@DataJpaTest`
- Full integration tests: `@SpringBootTest` plus Testcontainers with `@ServiceConnection`
- Mocks: `@MockitoBean` and `@MockitoSpyBean`. Never `@MockBean`
- One slice annotation per test class
- Every bug fix comes with a test that failed before the fix
## Config and secrets
- No passwords, tokens or keys in `application*.yaml` or in code
- Secrets come from environment variables, e.g. `SPRING_DATASOURCE_PASSWORD`
- Never print secrets or the full Environment in logs
## Do not
- Do not add a dependency without asking. Do not change the Spring Boot version
- Do not put classes in the default package or outside the root package
- Do not edit generated code under `target/`
## Gotchas
- A test slice loads only part of the context. Mock the services a slice needs
- Testcontainers containers stop after the test class; cached contexts may outlive them
- <Your service's own surprises: schemas, message brokers, feature flags>
What does each part of the template do?
Header and stack line. Naming Spring Boot 4.1, the Java version and the build tool stops Claude from guessing. As of October 2026, the Spring Boot docs cover Spring Boot 4.1.2, which is compatible with Java versions up to 27 and manages JUnit Jupiter 6.
Commands. The Spring Boot getting started guide runs apps with ./mvnw spring-boot:run or ./gradlew bootRun. The running your application page shows java -jar target/myapplication-0.0.1-SNAPSHOT.jar for a packaged app. The single-class test command comes from the Maven Surefire docs. spring-boot:test-run is the Maven goal the development-time services page gives for launching the app from the test classpath, which is how Testcontainers can supply a database while you develop. Spring Boot does not ship a formatter, so the format line is a placeholder for whatever your team uses.
Project structure. The structuring your code page recommends putting the main application class "in a root package above other classes", because @SpringBootApplication defines the base package for component scanning. Its example layout groups classes by feature, with a controller, service and repository per package. The profile files follow the externalized configuration docs: application-{profile} files override the shared file.
Spring rules. The dependency injection page says "We generally recommend using constructor injection", which also lets fields be final. The externalized configuration docs describe @ConfigurationProperties as a strongly typed alternative to @Value for groups of settings. Returning DTOs instead of entities and a single controller advice are common team conventions; keep or drop them. The Spring Boot 4 lines capture migration guide items that older examples get wrong: the guide says Jackson 3 moves com.fasterxml.jackson to tools.jackson (except the annotations module), and Spring Boot 4 is based on Jakarta EE 11.
Testing. The testing docs explain that each slice "restricts component scan to appropriate components", that using several slice annotations in one test "is not supported", and that MockMvcTester wraps MockMvc with AssertJ. The Testcontainers page shows @ServiceConnection defining connection details from a container, which needs the spring-boot-testcontainers test dependency.
Config and secrets. Spring Boot binds environment variables with underscores in place of dots, per the externalized configuration docs, so SPRING_DATASOURCE_PASSWORD maps to spring.datasource.password. Naming the variable shows Claude the pattern to follow for new settings.
Gotchas. The Testcontainers page warns that containers stop after the test class while Spring's test framework "may cache the ApplicationContext beyond that point", and recommends managing containers as beans when that matters.
Which agent mistakes does the template prevent?
| Without the rule | Line in the template that prevents it |
|---|---|
@MockBean in a new test, which no longer exists in Spring Boot 4 |
"Never @MockBean" |
com.fasterxml.jackson.databind imports in a Jackson 3 app |
The Jackson 3 line in the Spring rules |
| A new class placed outside the root package, so it is never scanned | "Do not put classes in the default package or outside the root package" |
@SpringBootTest used for every test, making the suite slow |
The slice lines in the testing section |
A database password committed in application.yaml |
"No passwords, tokens or keys in application*.yaml" |
Field injection with @Autowired |
"Constructor injection with final fields" |
Each new rule you add should prevent a mistake you have actually seen. If you cannot name the mistake, the line probably is not needed.
How do you adapt it to your project?
- Gradle: use
./gradlew bootRun,./gradlew bootTestRun,./gradlew test --tests OrderServiceTestand./gradlew build. The test filter syntax is in the Gradle testing docs. - WebFlux: replace the MVC lines with your reactive stack and its test slice.
- Multi-module build: put a short CLAUDE.md in each module folder. Claude Code loads CLAUDE.md files in subdirectories when it reads or edits files there. See the monorepo template for layout ideas.
- Docker Compose instead of Testcontainers: keep the
compose.yamlline. The dev services page says thespring-boot-docker-composemodule runsdocker compose upwhen the app starts and stops the services on shutdown. - Rules for one area: create
.claude/rules/persistence.mdwithpaths: ["src/main/java/**/*Repository.java"]in the frontmatter, so JPA rules load only when Claude touches a repository.
After saving, run /context in a Claude Code session and check that CLAUDE.md appears under Memory files. /init can draft a file from your code if you do not have one, and you can merge these sections into it.
Should you write an AGENTS.md version too?
If your team also uses Codex, Cursor or Copilot, move the shared content into AGENTS.md and keep CLAUDE.md small. Claude Code reads AGENTS.md by itself only when the project has no CLAUDE.md or CLAUDE.local.md, and only from v2.1.277, so import it:
@AGENTS.md
## Claude Code only
- Use plan mode before changing JPA entities or database migrations
- Run `/doctor prompt-audit` after editing AGENTS.md or this file
Claude reads AGENTS.md first, then the lines below the import. The AGENTS.md guide explains which tools read it, and Claude Code memory covers how root and module files combine.
How do you keep a Spring Boot CLAUDE.md useful?
Add a line when Claude makes the same mistake twice, and delete lines it follows anyway. When you upgrade Spring Boot, update the version line first and check the migration guide for renamed starters or annotations. /doctor prompt-audit (Claude Code v2.1.283 or later) finds outdated or conflicting instructions and proposes edits without changing anything until you ask. CLAUDE.md is context, not enforcement, so if a rule must never be broken, such as never running database migrations against production, use a hook.
If you set up Spring services often, keep the template somewhere reusable. Kipt stores prompts and Agent Skills as Markdown in a private GitHub repo you own, so you could save this as a prompt with blanks like {{build_tool:Maven}} and fill them per service. The Java prompts collection pairs well with it, and related templates cover .NET, Go and Laravel.