PlantUML Layout Guide: Direction, Spacing, and Nested Boxes

··Updated ·8 min read
plantumlplantuml-layoutnested-boxesdiagram-layout

PlantUML layout works best when you describe structure and give the automatic engine a few meaningful constraints. Start with overall direction, group related elements in semantic containers, adjust spacing only when necessary, and use hidden links as a last resort.

For color and typography, use the PlantUML colors and themes guide. For examples across diagram types, return to the PlantUML examples hub.

Key Takeaways

  • top to bottom direction is the familiar default for relevant graph-based diagrams; left to right direction often suits wide flows.
  • Nested package, node, and rectangle containers should communicate ownership or deployment boundaries.
  • nodesep and ranksep can improve breathing room but must be tested in the target renderer.
  • Hidden relationships can stabilize a difficult layout, but too many make source brittle.
  • OnUML has no layout-engine selector; a source pragma such as Smetana only works when the configured PlantUML rendering service supports it.

Layout Troubleshooting Quick Reference

ProblemFirst optionFallbackMain risk
Diagram is too tallAdd left to right directionSplit unrelated concerns into separate diagramsA wide result may overflow narrow documentation
Related elements drift apartGroup them in a meaningful package, node, or rectangleAdjust declaration orderEmpty grouping boxes used only for positioning obscure the model
Rows or columns feel crampedTune nodesep or ranksep modestlyShorten labelsLarge spacing values create oversized exports
One relationship routes poorlyAdd a restrained direction hint to that relationshipReorder nearby declarationsToo many hints make later edits unpredictable
Automatic layout remains unstableSimplify crossing relationshipsAdd one hidden relationshipInvisible constraints are difficult to maintain
A representative diagram renders poorlySimplify the graph firstTry !pragma layout smetana only if the OnUML preview accepts itRenderer support and output can change

Paste a representative example into the OnUML editor to compare source changes with the rendered PlantUML preview before committing layout constraints.

Before You Begin

What you need:

  • A PlantUML renderer with a known version
  • A diagram whose relationships are already correct
  • Both wide and narrow preview sizes
  • About 25 minutes
  • Difficulty: Intermediate

Do not begin by trying to recreate pixel coordinates from a slide. PlantUML is intentionally declarative and uses automatic layout.

Step 1: Choose the Main Direction

By the end of this step, the diagram's primary reading path will match its destination.

@startuml
left to right direction

actor Customer
rectangle "Web Application" as Web
rectangle "Order Service" as Orders
database "Order Database" as DB

Customer --> Web
Web --> Orders
Orders --> DB
@enduml

Change the directive to:

top to bottom direction

Render both versions. The PlantUML class diagram documentation describes direction controls and notes top-to-bottom as the default in that context. Choose the version that minimizes crossing lines and fits the content column.

Step 2: Group Elements with Meaningful Boxes

By the end of this step, boxes will describe system structure rather than merely push nodes around.

@startuml
left to right direction

actor Customer

rectangle "Commerce Platform" {
  package "Ordering" {
    component "Checkout API" as Checkout
    component "Order Service" as Orders
  }

  package "Payments" {
    component "Payment Adapter" as Adapter
  }
}

node "External Provider" {
  component "Payment Gateway" as Gateway
}

Customer --> Checkout
Checkout --> Orders
Checkout --> Adapter
Adapter --> Gateway
@enduml

Nested boxes work when each boundary answers a question: which subsystem owns this component, or where is it deployed? The deployment diagram documentation provides container forms such as node, while other diagram families support packages and rectangles.

Verify that removing a box would remove information, not only alter placement.

Step 3: Adjust Spacing Carefully

By the end of this step, labels and elements will have enough space without creating an oversized diagram.

@startuml
skinparam nodesep 45
skinparam ranksep 55
left to right direction

component Client
component API
component Worker
database Store

Client --> API : HTTPS
API --> Worker : queue
Worker --> Store : writes
@enduml

nodesep affects separation among nodes, while ranksep affects separation between ranks in compatible graph layouts. These remain skinparam settings, so test them with your diagram family and version. The skinparam reference is the official starting point.

Increase one value at a time. If labels overlap, shortening labels or changing direction can work better than extreme spacing.

Step 4: Influence Individual Relationships

By the end of this step, important edges will encourage a readable arrangement.

PlantUML supports direction hints on relationships:

@startuml
class Checkout
class Order
class Payment
class Customer

Customer -down-> Checkout
Checkout -right-> Order
Checkout -left-> Payment
@enduml

Treat hints as preferences within automatic layout, not guaranteed coordinates. Reverse an edge only when its semantic arrow remains correct; do not change dependency meaning merely to move a box.

Step 5: Use Hidden Relationships as a Last Resort

By the end of this step, you will know how to add a layout constraint without displaying another relationship.

@startuml
left to right direction

component Web
component API
component Worker

Web --> API
API --> Worker
Web -[hidden]-> Worker
@enduml

The hidden edge can influence relative ordering, but it adds invisible knowledge that future editors must understand. Add a visible note outside the diagram source documentation if the constraint is non-obvious. Prefer one stable hidden constraint over a web of layout-only edges.

Step 6: Try Smetana Carefully in OnUML

By the end of this step, you will know whether OnUML's configured PlantUML rendering service accepts the Smetana pragma and whether it improves this diagram.

OnUML does not expose a Graphviz/Smetana selector or renderer-version control. PlantUML documents Smetana through a source pragma, which you can try directly in the diagram:

@startuml
!pragma layout smetana

package Frontend {
  component Web
}
package Backend {
  component API
  database DB
}

Web --> API
API --> DB
@enduml

If the OnUML preview renders successfully, compare crossings and container sizing with and without the pragma. If the preview fails or becomes less stable, remove it. The layout engines documentation describes the PlantUML feature, but support is determined by OnUML's configured rendering service.

Step 7: Make the Source Stable

By the end of this step, future edits will be less likely to cause unexplained layout churn.

Use this order:

  1. Declare elements in a logical sequence.
  2. Add semantically correct relationships.
  3. Choose one global direction.
  4. Add meaningful containers.
  5. Tune modest spacing.
  6. Add at most a few relationship hints.
  7. Export a reference SVG after the OnUML preview is stable.

Then save one representative SVG as a review artifact. The source remains authoritative; the reference image makes unexpected changes visible.

Common Mistakes to Avoid

Fighting automatic layout too early. First simplify labels, remove accidental cycles, and choose an appropriate direction.

Using boxes only as positioning devices. Containers should encode ownership, deployment, or another real boundary.

Adding many hidden links. Invisible constraints interact and are difficult to debug after model changes.

Expecting a layout to remain pixel-identical forever. Renderer changes can affect ordering and spacing. Keep the source simple and compare an exported reference SVG when visual stability matters.

Solving styling problems with layout. A crowded diagram may need lower information density or clearer hierarchy, not just larger ranksep.

What Success Looks Like

A successful layout has a clear reading direction, few crossing edges, meaningful nested boundaries, and little or no invisible constraint logic. It also remains understandable in the page width where readers will see it.

Frequently Asked Questions

How do I make PlantUML flow left to right?

Add left to right direction near the start of the diagram. Verify the result because containers and relationships still affect automatic placement.

How do I create nested boxes in PlantUML?

Nest supported containers such as package, node, or rectangle, depending on the diagram type. Use each boundary to express meaning.

Can I position a PlantUML element at exact coordinates?

PlantUML's normal workflow is automatic layout rather than pixel coordinates. Direction hints and constraints influence the result but do not provide a general absolute-position canvas.

Should I use Graphviz or Smetana?

OnUML does not provide an engine selector. Keep the default unless a tested !pragma layout smetana improves the current preview; remove the pragma if the configured rendering service does not support it.

Official Sources

  • PlantUML class diagram direction and relations
  • PlantUML deployment diagrams
  • PlantUML layout engines
  • PlantUML skinparam

Start with structure, then add the smallest useful layout constraint. If visual hierarchy still feels weak, refine it with the PlantUML colors and themes guide. If relationship density is the real problem, simplify the model with the PlantUML class diagram guide; if the diagram type itself needs reconsideration, use the PlantUML examples hub.