The problem
Spring Modulith's built-in Documenter is excellent — and it only speaks AsciiDoc and PlantUML.
Docusaurus speaks Markdown and Mermaid. Hand-converting the output (or worse, hand-writing a parallel set of
docs) drifts from the real module structure the moment anyone adds a bean, an event, or a dependency.
What it does
Same facts
Every module's beans, events, aggregates, value types and config properties — the same set Spring Modulith itself documents, read straight from the public model.
Same diagrams
Diagrams come from the identical Structurizr workspace Documenter builds, exported to Mermaid directly — never a lossy PlantUML-to-Mermaid text conversion.
Provably in sync
A semantic parity test runs both tools over the same ApplicationModules instance and fails the build the moment they disagree on a fact or a diagram edge.
Generated Markdown → rendered docs
No mockup here: this is the real output of ModulithDocusaurusRenderer run over the
two-module sample fixture the semantic parity test uses. The file on the left is what lands in your
docs/ tree; the right is that same file rendered live, Mermaid diagram included.
---
id: order
title: Order
sidebar_label: Order
sidebar_position: 2
---
# Order
```mermaid
graph TB
linkStyle default fill:#ffffff
subgraph diagram ["Order"]
style diagram fill:#ffffff,stroke:#ffffff
subgraph 1 ["SampleApplication"]
style 1 fill:#ffffff,stroke:#444444,color:#444444
subgraph 2 ["SampleApplication"]
style 2 fill:#ffffff,stroke:#444444,color:#444444
3["<div style='font-weight: bold'>Inventory</div><div style='font-size: 70%; margin-top: 0px'>[Component: Module]</div>"]
style 3 fill:#ffffff,stroke:#444444,color:#444444
4["<div style='font-weight: bold'>Order</div><div style='font-size: 70%; margin-top: 0px'>[Component: Module]</div>"]
style 4 fill:#ffffff,stroke:#444444,color:#444444
end
end
4-. "<div>uses</div><div style='font-size: 70%'></div>" .->3
end
```
## Description
Handles order placement and the lifecycle of an order, from creation to fulfillment.
## Base package
`li.selman.modulithdocsmarkdown.sample.order`
## Spring components
- `OrderProperties`
- `OrderRepository`
- `OrderService`
## Bean references
- `InventoryLookup` (in [Inventory](./inventory))
## Aggregate roots
- `Order`
## Value types
- `OrderId`
## Published events
- `OrderPlaced`
## Events listened to
- `StockLevelChanged`
## Configuration properties
- `app.order.max-items-per-order` -- `java.lang.Integer`, default `10`. Maximum number of items allowed on a single order.
Order
graph TB
linkStyle default fill:#ffffff
subgraph diagram ["Order"]
style diagram fill:#ffffff,stroke:#ffffff
subgraph 1 ["SampleApplication"]
style 1 fill:#ffffff,stroke:#444444,color:#444444
subgraph 2 ["SampleApplication"]
style 2 fill:#ffffff,stroke:#444444,color:#444444
3["<div style='font-weight: bold'>Inventory</div><div style='font-size: 70%; margin-top: 0px'>[Component: Module]</div>"]
style 3 fill:#ffffff,stroke:#444444,color:#444444
4["<div style='font-weight: bold'>Order</div><div style='font-size: 70%; margin-top: 0px'>[Component: Module]</div>"]
style 4 fill:#ffffff,stroke:#444444,color:#444444
end
end
4-. "<div>uses</div><div style='font-size: 70%'></div>" .->3
end
Description
Handles order placement and the lifecycle of an order, from creation to fulfillment.
Base package
li.selman.modulithdocsmarkdown.sample.order
Spring components
OrderPropertiesOrderRepositoryOrderService
Bean references
InventoryLookup(in Inventory)
Aggregate roots
Order
Value types
OrderId
Published events
OrderPlaced
Events listened to
StockLevelChanged
Configuration properties
app.order.max-items-per-order--java.lang.Integer, default10. Maximum number of items allowed on a single order.
Usage
Add the dependency (see latest release for the version):
<dependency>
<groupId>li.selman</groupId>
<artifactId>modulith-docs-markdown</artifactId>
<version>VERSION</version>
</dependency>
Then render your modules into your Docusaurus docs/ tree:
var modules = ApplicationModules.of(MyApplication.class).verify();
new ModulithDocusaurusRenderer(modules)
.writeTo(Path.of("docs/modules"));
Full walkthrough, including the Docusaurus securityLevel note and the table-vs-sections
switch, is in the README.