Living Sequence Diagrams - Automatically generate interactive sequence diagrams from your code
LSD Core transforms how you document system interactions. Instead of manually maintaining sequence diagrams that quickly become stale, capture interactions programmatically and generate living documentation that stays in sync with your code.
Key Features:
- Generate sequence diagrams without writing PlantUML markup
- Interactive HTML reports with clickable event details
- Component diagrams showing system-wide relationships
- Automatic diagram splitting for complex flows
- Multiple output formats and customizable themes
Use Cases:
- Document API interactions in integration tests
- Visualize microservice communication patterns
- Debug complex distributed system flows
- Generate architecture documentation from tests
- Create onboarding materials automatically
@startuml
User -> API: POST /login
API -> Database: SELECT * FROM users
Database --> API: user data
API --> User: 200 OK
@endumlProblems:
- Manual maintenance required
- Quickly becomes outdated
- No connection to actual code
- Limited interactivity
// In your test or application code
lsd.capture(
("User" messages "API") { label("POST /login") },
("API" messages "Database") { label("SELECT * FROM users") },
("Database" respondsTo "API") { label("user data") },
("API" respondsTo "User") { label("200 OK") }
)Benefits:
- Generated from actual execution
- Always in sync with code
- Interactive HTML with details
- Automatic from tests
| Feature | Description |
|---|---|
| Zero Markup | No PlantUML syntax to learn - just Java/Kotlin code |
| Living Documentation | Diagrams generated from actual execution, not manual drawings |
| Interactive Reports | Click any interaction to see full request/response details |
| Multiple Diagrams | Sequence diagrams + component diagrams from same data |
| Test Integration | JUnit 5 and Cucumber plugins available |
| HTTP Interception | Auto-capture REST/HTTP calls with interceptors |
| Customizable | Themes, colors, participant types, custom icons |
| Large Diagram Support | Auto-splitting for complex flows |
| Offline Mode | Works without internet (inline CSS/JS) |
Add the dependency to your project:
Maven
<dependency>
<groupId>io.github.lsd-consulting</groupId>
<artifactId>lsd-core</artifactId>
<version>X.X.X</version>
</dependency>Gradle
implementation 'io.github.lsd-consulting:lsd-core:X.X.X'Capture interactions using the LsdContext singleton:
Kotlin Example
(Kotlin DSL as below or alternatively use the Java style builder or create Message() instances directly)
fun main() {
val lsd = LsdContext.instance
// Capture message exchanges
lsd.capture(
("User Service" messages "Auth Service") { label("POST /authenticate") },
("Auth Service" respondsTo "User Service") {
label("200 OK")
data("<token>")
}
)
// Complete the scenario and generate report
lsd.completeScenario("User Authentication Flow")
lsd.completeReport("Authentication API")
}Java Example
public static void main(String[] args) {
LsdContext lsd = LsdContext.getInstance();
lsd.capture(
messageBuilder()
.from("User Service")
.to("Auth Service")
.label("POST /authenticate")
.build(),
messageBuilder()
.from("Auth Service")
.to("User Service")
.label("200 OK")
.data("<token>")
.type(SYNCHRONOUS_RESPONSE)
.build()
);
lsd.completeScenario("User Authentication Flow");
lsd.completeReport("Authentication API");
}Output: The generated HTML report will be in build/reports/lsd/ (configurable via properties).
Here's how you might document an order processing flow:
@Test
fun `process order with payment`() {
val lsd = LsdContext.instance
// Customer places order
lsd.capture(
("Customer" messages "Order Service") { label("POST /orders {items, total}") }
)
// Order service validates and requests payment
lsd.capture(
("Order Service" messages "Payment Service") { label("POST /payments") },
("Payment Service" respondsTo "Order Service") { label("200 OK"); data("<transactionId>") }
)
// Order confirmed
lsd.capture(
("Order Service" respondsTo "Customer") {
label("201 Created")
data("<orderId>")
}
)
lsd.completeScenario("Successful Order Processing")
lsd.completeReport("E-Commerce API Flows")
}This generates an interactive diagram showing the complete flow, with each arrow clickable to reveal request/response details.
Enhance diagrams with typed participants that have custom colors and aliases:
// Define participants with visual styling
val frontend = BOUNDARY.called("Web App", "Frontend", "#3498db")
val api = CONTROL.called("API Gateway", "Gateway", "#2ecc71")
val userDb = DATABASE.called("PostgreSQL", "User DB", "#e74c3c")
val cache = DATABASE.called("Redis", "Cache", "#f39c12")
val queue = QUEUE.called("RabbitMQ", "Event Queue", "#9b59b6")
// Register participants for consistent styling across scenarios
lsd.addParticipants(listOf(frontend, api, userDb, cache, queue))
// Use in messages
lsd.capture(
(frontend messages api) {
label("GET /users/123")
data("data for report diagram popup (may contain json, xml, html)")
}
)Available Participant Types:
| Type | Visual | Best For |
|---|---|---|
ACTOR |
Stick figure | End users, external actors |
BOUNDARY |
Box with side bar | UI components, API boundaries |
CONTROL |
Circle with arrow | Controllers, orchestrators |
DATABASE |
Cylinder | Databases, data stores |
ENTITY |
Circle | Domain entities, models |
QUEUE |
Queue icon | Message queues, event streams |
COLLECTIONS |
Stacked boxes | Collections, lists |
PARTICIPANT |
Simple box | Generic components (default) |
Beyond messages, capture additional context with these event types:
// Add a title to the diagram
lsd.capture(PageTitle("User Registration Flow"))
// Add explanatory notes
lsd.capture(NoteOver("API", "Validates email format"))
lsd.capture(NoteLeft("Database", "Checks for existing user"))
lsd.capture(NoteRight("Email Service", "Sends welcome email"))
// Show async operations or delays
lsd.capture(TimeDelay("Processing..."))
// Split complex flows into multiple pages
lsd.capture(Newpage("Payment Processing"))
// Show active processing (useful for async operations)
lsd.capture(ActivateLifeline("Payment Processor", "#ff6b6b"))
// ... processing events ...
lsd.capture(DeactivateLifeline("Payment Processor"))Available Event Types:
| Event | Use Case | Example |
|---|---|---|
PageTitle |
Set diagram title | PageTitle("Authentication Flow") |
NoteLeft |
Add context to the left | NoteLeft("API", "Rate limited") |
NoteRight |
Add context to the right | NoteRight("DB", "Cached result") |
NoteOver |
Add context over lifeline | NoteOver("Service", "Retry logic") |
TimeDelay |
Show elapsed time | TimeDelay("5 seconds") |
Newpage |
Split into pages | Newpage("Error Handling") |
ActivateLifeline |
Show active processing | ActivateLifeline("Worker", "red") |
DeactivateLifeline |
End active processing | DeactivateLifeline("Worker") |
Generate an index page for multiple reports:
lsd.createIndex()Create component diagrams showing relationships across all scenarios:
lsd.completeComponentsReport("Relationships")Highlight important information with facts:
// The keyword "Lorem" will be highlighted throughout the report
lsd.addFact("Something to highlight", "Lorem")Include custom icons (e.g., Font Awesome):
lsd.includeFiles(listOf("tupadr3/font-awesome-5/heart"))
lsd.capture(NoteLeft("Friends <$heart{scale=0.4,color=red}>"))Customize LSD behavior by adding an lsd.properties file to your classpath or setting system properties (which take precedence).
| Property | Default | Description |
|---|---|---|
lsd.core.label.maxWidth |
200 |
Maximum label width (in characters) before abbreviation |
lsd.core.diagram.theme |
plain |
PlantUML theme (available themes) |
lsd.core.report.outputDir |
build/reports/lsd |
Output directory for report files |
lsd.core.ids.deterministic |
false |
Generate deterministic HTML element IDs (useful for approval testing) |
lsd.core.diagram.sequence.maxEventsPerDiagram |
50 |
Maximum events per diagram before auto-splitting |
lsd.core.devMode |
true |
Offline mode with inline CSS/JS (no CDN dependencies) |
lsd.core.metrics.enabled |
false |
Experimental: Show performance metrics table |
Sequence Diagrams with Metrics
|
Interactive Popups Click arrows to view detailed event data
|
|
Component Diagrams Visualize all participants across scenarios
|
Index Pages Navigate between multiple reports
|
LSD Core is the foundation library. Several companion libraries automate diagram generation for popular testing frameworks:
- lsd-junit-jupiter - JUnit Jupiter extension
- lsd-junit5 - JUnit 5 extension (deprecated)
- lsd-cucumber - Cucumber plugin
- lsd-interceptors - HTTP/messaging interceptors
- More libraries...
How does LSD differ from manually writing PlantUML?
LSD generates diagrams from actual code execution, ensuring they stay synchronized with your implementation. You can capture events during tests, and the diagrams are always accurate.
Can I use LSD with existing test frameworks?
Yes! Check out the Ecosystem section for integrations with JUnit, Cucumber, and HTTP interceptors that automatically capture interactions.
What's the performance impact?
LSD is designed for test and development environments. In production, you can disable event capture or use conditional logic. Event capture is lightweight, but diagram generation should happen offline.
Can I customize the diagram appearance?
Yes! You can use any PlantUML theme, customize participant colors, add notes, and control diagram layout. See Configuration and Advanced Features.
How do I handle large diagrams?
LSD automatically splits diagrams when they exceed lsd.core.diagram.sequence.maxEventsPerDiagram (default: 50 events). You can also manually split using Newpage events.
- Java 17 JDK
./gradlew clean buildGit hooks are configured automatically on first build (uses .githooks directory).
Static files (CSS/JS) are cached on JSDelivr CDN for up to 7 days. To force a cache refresh:
- Use the JSDelivr Purge tool
- Purge these files:
https://cdn.jsdelivr.net/gh/lsd-consulting/lsd-core@5/src/main/resources/static/style.min.csshttps://cdn.jsdelivr.net/gh/lsd-consulting/lsd-core@5/src/main/resources/static/custom.min.js
- Clear your browser cache
Tip: Use lsd.core.devMode=true (default) to avoid CDN issues during development.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE.txt file for details.




