How do you generate module documentation and diagrams with Spring Modulith's Documenter, and what output do you get?
answer
- new Documenter(modules).writeDocumentation()
- .puml component diagrams (aggregate + per-module)
- Application Module Canvas (Markdown: events, deps, interfaces)
- DiagramOptions.DiagramStyle: UML vs C4
- output → target/spring-modulith-docs
basics
~10 sYou create a Documenter from your ApplicationModules and call methods like writeDocumentation(). It emits PlantUML component diagrams (per module and an overview) plus a Markdown 'module canvas', into target/spring-modulith-docs by default.
solid answer
~40 sDocumenter takes the same ApplicationModules model that verify() uses and renders documentation from it. new Documenter(modules).writeDocumentation() produces PlantUML (.puml) component diagrams — one aggregate diagram of all modules and one per module showing its dependencies — plus an 'Application Module Canvas' in Markdown per module (exposed interfaces, dependencies, published events, configuration). You can choose the diagram style via Documenter.DiagramOptions, switching between UML component style and C4 style, and adjust output paths. It's typically driven from the same test that runs verify(), so docs regenerate on every build and never drift from the actual code structure. Rendering the .puml to images needs PlantUML tooling in the pipeline.
code
java · 18 linesimport org.springframework.modulith.core.ApplicationModules;
import org.springframework.modulith.docs.Documenter;
class DocumentationTests {
ApplicationModules modules = ApplicationModules.of(ShopApplication.class);
@Test
void writeDocs() {
// C4-style diagrams + canvases + aggregate PlantUML
var options = Documenter.DiagramOptions.defaults()
.withStyle(Documenter.DiagramOptions.DiagramStyle.C4);
new Documenter(modules)
.writeModulesAsPlantUml(options)
.writeIndividualModulesAsPlantUml(options)
.writeModuleCanvases();
}
}go deeper
Know new Documenter(modules).writeDocumentation() produces PlantUML diagrams and a Markdown canvas.
Explain the aggregate vs per-module diagrams, the canvas contents, and .puml (not images) output.
Cover DiagramOptions/DiagramStyle for UML-vs-C4 and wiring doc generation into the verify test.
Discuss living-docs strategy, rendering pipeline needs (PlantUML/C4 macros), and detection blind spots shared with verify().
## Purpose Boundaries are only useful if people can see them. `org.springframework.modulith.docs.Documenter` turns the **same module model** (`ApplicationModules`) that powers `verify()` into human-readable artifacts. Because it reads the real code, the docs can't drift from reality — regenerate them on every build. ## Creating and running it ```java ApplicationModules modules = ApplicationModules.of(ShopApplication.class); new Documenter(modules).writeDocumentation(); ``` `writeDocumentation()` is a convenience that writes the full set. There are finer-grained methods too: - `writeModulesAsPlantUml(...)` — the **aggregate** diagram (all modules + inter-module edges). - `writeIndividualModulesAsPlantUml(...)` — **one diagram per module** showing that module and what it depends on. - `writeModuleCanvases(...)` — the **Application Module Canvas** per module. ## What you get 1. **PlantUML component diagrams** (`.puml` text files). PlantUML is a text-to-diagram tool; the files describe boxes (modules) and arrows (dependencies). You render them to PNG/SVG with the PlantUML CLI or a build plugin. 2. **Application Module Canvas** — a **Markdown** table per module summarizing: exposed types / named interfaces, dependencies on other modules, **published and consumed events**, aggregates, and Spring configuration/properties the module owns. It's a compact, reviewable 'contract card' for each module. Default output directory is `target/spring-modulith-docs` (Maven) — configurable. ## Choosing the diagram style: PlantUML vs C4 `Documenter.DiagramOptions` controls rendering. Its `DiagramStyle` lets you pick: - **`UML`** — classic PlantUML component style. - **`C4`** — the C4 model component notation (needs the C4-PlantUML macros available to your renderer). ```java Documenter.DiagramOptions options = Documenter.DiagramOptions.defaults() .withStyle(Documenter.DiagramOptions.DiagramStyle.C4); new Documenter(modules).writeModulesAsPlantUml(options); ``` You can also constrain which dependency types appear, set output file names, and target a specific `CanvasOptions` for the Markdown canvas. ## Typical wiring Put it in the very test that verifies structure so docs and enforcement stay in lockstep: ```java @Test void writeDocs() { new Documenter(modules).writeDocumentation(); } ``` ## Gotchas - Documenter emits **.puml text**, not images. To get pictures in CI you still need PlantUML (and, for C4 style, the C4-PlantUML includes) in the pipeline. - Diagrams reflect *detected* dependencies; if a dependency exists only via reflection, it won't appear (same blind spot as verify()). - The canvas surfaces **events** only when Modulith can detect them (e.g. `ApplicationEvent`/`@DomainEvent`-style publications it can resolve statically). - Output goes under the build directory by default — don't hand-edit generated files; regenerate. ## When to use Whenever you want living architecture docs: onboarding, architecture reviews, or embedding module diagrams in an Antora/reference-docs site. Pairs naturally with `verify()`.
- Does Documenter produce PNG/SVG images directly?No — it writes PlantUML (.puml) text files (and Markdown canvases). You render them to images separately with PlantUML tooling; C4 style additionally needs the C4-PlantUML macros.
- What extra information does the Application Module Canvas add beyond the diagram?A Markdown summary per module: exposed types/named interfaces, module dependencies, published and consumed events, aggregates, and owned Spring configuration/properties — a reviewable module 'contract card'.
saying these in an interview costs you the question
- Claiming Documenter outputs rendered images rather than .puml text
- Saying C4 vs UML is chosen in application.yml instead of DiagramOptions
- Confusing the canvas (Markdown) with the diagram (PlantUML)