drumlin
drumlin turns a small text format into UML diagrams that look drafted by hand: aligned boxes, even spacing, orthogonal lines and restrained type.
diagram component "Order Platform"
direction right
package "Edge" {
component "Web Gateway" as gateway {
requires IOrders
requires IIdentity
}
}
component "Order Service" as orders {
port api provides IOrders
port events requires IEventBus
component "API Handler" as handler { requires IPricing }
component "Pricing Engine" as pricing { provides IPricing }
component "Outbox" as outbox
api --> handler
handler --> outbox : persist
outbox --> events
}
component "Identity" as identity <<external>> { provides IIdentity }
package "Infrastructure" as infra {
component "Event Bus" as bus { provides IEventBus }
component "Postgres" as db <<database>>
align bus db
}
component "Billing" as billing {
requires IEventBus
provides IInvoices
}
orders ..> db : SQL
note outbox: Publishes at least once. Consumers deduplicate on event id.
Every diagram on this site was rendered from the source shown beside it, while the site was being built. See Rendering at docs build time.
Why drumlin
- It is written in Rust with no runtime. One small binary, with no JVM, browser or Graphviz.
- The syntax is easy to read and write. It follows the feel of PlantUML with one regular grammar.
- Output is deterministic. The same input gives byte-identical SVG, so diagrams diff cleanly in code review.
- Errors are precise. Each has a line, a column and, when possible, a suggestion.
Status
drumlin is a prototype. Component, package, sequence, state and activity diagrams are implemented, and their notation has been audited against UML 2.5.1. Further work and known limitations are on the roadmap.
Finding your way
To draw something, start under Diagrams: each kind has a complete how-to and a page of examples. To see what one symbol looks like, go to Elements.
In the diagram above, matched interface names do the wiring: the portless ends keep socket and lollipop apart, joined by a dashed arrow. Only two simple ports get a joined ball-and-socket. See Interface.