opencode is a terminal coding agent that can work directly inside an existing Spring Boot project. This guide shows how to configure it with Maven or Gradle, write an AGENTS.md that reflects your stack, and drive it through real controller, service, JPA, and Testcontainers work. It assumes you already know Spring Boot and want predictable output from the agent.
Spring Boot’s conventions make opencode useful
Spring Boot projects are convention-heavy: package structure, annotation wiring, dependency versions, and test slicing all matter. opencode reads the project tree, Maven or Gradle build files, and AGENTS.md, so once you encode those conventions the agent can generate controllers, services, and repositories that match your existing Java style. It can also run your test command and read stack traces, which makes the feedback loop concrete. For a closer look at the agent itself, see opencode. Unlike a generic chat model, opencode operates as a CLI agent in the repository, so it can apply multi-file edits across controller, service, and repository layers without leaving the terminal.
Give the agent the build and package rules up front
Create an AGENTS.md in the project root before asking opencode to change code. The file should be short but specific: exact build and test commands, package layout, and Spring Boot rules you never want it to break. Do not copy a generic Java AGENTS.md; include your dependency manager, test slice preferences, and any conventions around records, Lombok, or transaction boundaries.
# AGENTS.md
## Build and test
- Maven: ./mvnw clean verify
- Gradle: ./gradlew clean test
- Run a single test: ./mvnw -Dtest=OrderControllerTest test
- No lint command; use ./mvnw checkstyle:check if configured.
## Project layout
- src/main/java/com/acme/orderapp
- controller/ -> REST controllers, thin, delegate to services
- service/ -> business logic, @Service, @Transactional on write operations
- repository/ -> Spring Data JPA interfaces only, no implementation classes
- dto/ -> request/response records or immutable classes
- entity/ -> JPA entities, avoid Lombok unless already in pom
- src/test/java/com/acme/orderapp
- unit tests in service/, slice tests with @WebMvcTest, integration tests with @SpringBootTest and Testcontainers PostgreSQL
## Spring Boot rules
- Controllers return ResponseEntity<T>, use constructor injection only.
- Validate request DTOs with jakarta.validation annotations, add @Valid in controller method argument.
- Services throw custom exceptions; controllers map them with @RestControllerAdvice.
- Do not add new dependencies without asking. Use existing pom.xml or build.gradle.
- For tests, prefer JUnit 5 and AssertJ. Use Testcontainers only for integration tests that need PostgreSQL/RabbitMQ.
If you use Maven, replace Gradle commands accordingly. The key is that opencode will follow these rules when generating tests or refactoring, so avoid listing every file.
Plan small, run tests, review the diff
Use a plan-first loop. When you open opencode, ask it to summarize the relevant files before editing: the controller, service, repository, and any DTOs. Then give one small task, run the tests, and review git diff before accepting. For larger changes, split into: add DTO and entity validation, add service method, add controller endpoint, add slice test, then integration test. For step-by-step usage, How to use opencode: a step-by-step guide covers the CLI workflow.
Example prompts for typical Spring Boot work:
- “Add a GET /orders/{id} endpoint that returns an OrderResponse from OrderService; use constructor injection and return 404 when the service throws OrderNotFoundException.”
- “Create OrderService.placeOrder that saves Order and OrderItem in one transaction with @Transactional and validates that the customer exists.”
- “Write a @WebMvcTest for OrderController with @MockBean OrderService; cover 200 with a valid id and 404 with an unknown id.”
- “Add a Testcontainers PostgreSQL integration test for OrderRepository that saves and finds an order with order items.”
- “Refactor the exception handler in OrderControllerAdvice to return RFC 7807 problem details and update any affected tests.”
After each prompt, run ./mvnw test or ./gradlew test, and inspect git diff. If the change touches Spring configuration or dependencies, review those files manually.
Where opencode excels and where to double-check it
opencode handles the repetitive parts well: REST endpoints, JPA query methods, DTO mapping, validation, and test scaffolding. The table below shows tasks, good prompts, and pitfalls.
| Task | Good prompt | Watch closely |
|---|---|---|
| Add endpoint | “Add POST /orders with @Valid request body and return 201 with location header.” | It may add a service method but forget transaction or DTO validation. |
| Spring Data JPA | “Add a repository method to find all orders by customer id and status, sorted by created date.” | It may create a derived method that generates an inefficient query or ignores fetch size. |
| Service logic | “Create OrderService.cancelOrder with business rules: only pending orders can be cancelled, and update status.” | It may put business rules in the controller or skip @Transactional on read-write operations. |
| Testcontainers | “Write an integration test for inventory reduction using PostgreSQL Testcontainers.” | It may start a container for every test class instead of reusing a singleton, slowing builds. |
Other pitfalls: it may suggest changing pom.xml or build.gradle for features already available in Spring Boot; ask it first or set a rule in AGENTS.md. It may also generate tests that assert only HTTP status and not the response body, so add assertion requirements in the prompt.
Keep tests green with slice tests and Testcontainers
Make opencode run tests after each change. Tell it to run the specific test class first, then the full suite. For Maven, ./mvnw -Dtest=OrderControllerTest test; for Gradle, ./gradlew test —tests com.acme.orderapp.controller.OrderControllerTest. Verify Testcontainers tests clean up after themselves; opencode sometimes leaves containers running if it does not use singleton containers or @Testcontainers(disabledWithoutDocker = true). Check that integration tests do not rely on a shared embedded database when production uses PostgreSQL; prefer Testcontainers and the same RDBMS. Review application-test.yml or test properties for hard-coded ports and credentials. If you use JUnit 5, ask the agent to extend your base integration test class instead of re-implementing container config.
Run parallel Spring Boot agents with AgentVera
Spring Boot features often span multiple layers, so parallel agents can help when the change is large enough. AgentVera runs opencode and other CLI agents in real terminal panels, and each can work in its own git worktree, which prevents controller, service, and test changes from overwriting each other. Automatic code review with file:line links catches cross-layer mistakes such as a controller returning an entity instead of a DTO or a service missing a transaction. Token budgets keep experiments bounded, and when an agent hits a cap it stops but keeps its conversation for later handoff. This matches the way Spring Boot teams split work; see Best tools to run AI coding agents in parallel (2026) for the parallel approach.
Closing thoughts
Set up an AGENTS.md with exact Maven or Gradle commands, package conventions, and Spring Boot rules, then drive opencode in small, test-verified steps. Review every diff for dependency changes, transaction boundaries, and Testcontainers lifecycle. With that discipline, opencode becomes a reliable pair on real Spring Boot feature work.