---
title: "Layout and Tidy up"
description: "Tidy a workflow's layout with one click, one node at a time, from the console, or through an agent — and set the spacing it keeps."
source: https://flowdrop.io/docs/editor/layout
site: FlowDrop documentation
---
# Layout and Tidy up
A workflow that grew by hand ends up with cards on top of each other, wires that
double back, and wires that run straight through a port they have nothing to do with.
**Tidy up** puts that right without you moving a card: it picks a layout that reads
left to right, keeps your cards apart, straightens what it can, and leaves the
workflow alone when it cannot do better.
## Tidy up
| Where | Entry | Shortcut | What it tidies |
| --- | --- | --- | --- |
| Canvas controls | The **broom** button | `Shift + Alt + T` | The whole workflow |
| Canvas (pane) menu | **Tidy up** | `Shift + Alt + T` | The whole workflow |
| Node menu | **Tidy node** (**Tidy 3 nodes** with a multi-selection) | `Shift + S` | The selected node, or each selected node in turn |
The buttons are absent when the canvas is read-only or locked. The shortcuts work
with the canvas focused (or nothing focused, after a click on the empty canvas);
`Shift + S` needs at least one selected node.
- **One undo step.** Tidying several nodes is one step too.
- **The cards slide** to their new places (about a quarter of a second; not at all
under reduced motion).
- **A toast says what happened**, for example *Tidied up: 2 overlaps fixed · 3 wires
straightened · 1 crossing removed*, with an **Undo** button. When something had to
get worse to fix something more important, the toast says so (*but 1 more crossing*).
- **Nothing to gain, nothing moves.** You get *Layout is already tidy* (*Node is
already tidy*), and no undo step is recorded.
- **Big workflows are refused.** Tidy up works on up to 120 nodes. Above that, the
toast reads *Too many nodes to tidy at once*; the error is `graph too large to tidy`.
Tidy single nodes instead, which has no limit.
- **Notes and captions never move.** They are fixed obstacles: cards keep clear of them
and no layout step moves or reorders them.
Tidy up keeps the top-left corner of your workflow where it was and keeps every card
on the 20 px layout grid, so a tidied workflow does not drift across the canvas.
## What "tidy" means
A layout is judged by a fixed list, in priority order. A better result on an earlier
item always wins over any gain on a later one:
1. **No overlaps and enough spacing.** Cards never overlap, and keep the
[gap](#spacing-and-lanes) from each other: the horizontal gap between cards side by
side, the vertical gap between stacked cards. Diagonal neighbours need no gap.
2. **No wire through a port it does not belong to.** A wire passing straight through an
unconnected port looks as if it started or ended there.
3. **Straight wires.** A wire is straight when it is level *and* runs left to right.
Loopbacks do not count.
4. **Wires run forward.** Left to right, not back across the cards.
5. **Fewer crossings.**
6. **Fewer near misses.** A wire passing 10 to 20 px from a port that is not its own.
7. **Least movement.** Of two equal layouts, the one that moves cards less.
Only the first two can bend a wire that was straight. The rest never trade away a
straight wire.
Tidy up **keeps your layout unless the result is better** on items 1 to 6. A layout
that would end up equal or worse is thrown away, so running it twice is harmless.
Four moves do the work, tried one node at a time and each kept only if it improves the
score of the whole workflow:
| Move | What it changes |
| --- | --- |
| `column` | The card's `x`: into its column, one step right of what feeds it, then up or down to find room. |
| `ports` | The order of the card's connected ports, so wires stop crossing. Only connected data ports move, within the slots they hold. The branch outputs of a gateway are never reordered; the cards they lead to move instead. |
| `align` | The card's `y`, so one of its wires runs level. |
| `clear` | The card's `y`, only to leave an overlap, a too-tight spacing, or a wire passing through a port. |
`align` and `clear` move cards vertically only; only `column` changes `x`.
Tidy up on the whole workflow puts every card in its column first, then clears
conflicts, then runs `ports` and `align` until a pass changes nothing.
## From the console and the AI Assistant
The command console (and the [AI Assistant](/editor/ai-assistant), which runs the same
commands) has three layout commands besides `layout auto`.
```text
layout node inspect [--gap-x ] [--gap-y ]
layout node beautify [column|ports|align|clear|all] [--dry-run] [--gap-x ] [--gap-y ]
layout beautify [--dry-run] [--gap-x ] [--gap-y ]
```
### `layout node inspect`
Reports how one node sits on the canvas and changes nothing. Run it before you
beautify to see what is wrong.
```text
> layout node inspect compose
compose y=160 inputs: contact, label outputs: reply
in contact ← lookup.contact off by 40 crosses classify.label → compose.label
out reply → loop.items straight
overlaps none · spacing ok
```
For each wire the report says `straight`, `off by `, `backward` or `loopback`, and
names the wires it crosses. The last line lists the card's conflicts: `overlap with`,
`spacing with` a neighbour, or `lane with` a return lane. For a note or caption it
says `fixed obstacle`.
### `layout node beautify`
Tidies one node. The strategy is one of the moves above, or `all` (the default),
which runs `column`, `ports`, `align` and `clear` in that order. Only that node moves.
```text
> layout node beautify compose --dry-run
> layout node beautify compose align
> layout node beautify compose all --gap-x 160
```
It prints what changed and the score before and after (`straight 0 → 1 · crossings
3 → 2 · overlaps 1 → 0 · spacing ok`), or `no change` with the reason. `--dry-run`
only previews: the output says `would move` instead of `moved`. One undo step.
### `layout beautify`
The whole-workflow tidy: the same thing as **Tidy up**. It prints a line per step
and the score before and after, or says the layout is already as good as it gets.
`--sweep` is still accepted and changes nothing. Above 120 nodes it fails with
`TOO_LARGE`, and points at `layout node beautify`.
### Gaps
`--gap-x` and `--gap-y` override the [layout gap settings](#spacing-and-lanes) for one
call. A gap must be a non-negative multiple of the 20 px layout grid; anything else
fails with `INVALID_ARGUMENT`:
```text
--gap-x 30 is not valid: a gap must be a non-negative multiple of the 20 px layout grid (0, 20, 40, ...)
```
The flags can come in any order after the node id and strategy.
## Spacing and lanes
In **Settings → Editor**:
| Setting | Default | What it does |
| --- | --- | --- |
| **Layout gap between columns** (`layoutGapX`) | `120` | Space kept between cards side by side, in px. |
| **Layout gap between stacked cards** (`layoutGapY`) | `40` | Space kept between cards one above the other, in px. |
Gaps are at least 0 and are rounded to the grid. Tidy up, `layout beautify`,
`layout node beautify` and `layout node inspect` all read them; the console flags and
the agent tools' `gapX` / `gapY` override them for a single call.
```ts
updateSettings({ editor: { layoutGapX: 160, layoutGapY: 60 } });
```
**Return lanes.** A loop's `loop_back` wire is always drawn as a lane: out of the
source, down under the loop body, back along a lane 40 px below its lowest card, and up
into the port. Nested loops get nested lanes, and several loopbacks stack 20 px apart.
Layout keeps the lanes free of cards, so the loop body keeps the room below it. There is
no setting for it. Until every card of a loop body has been measured on the canvas, its
loopback is drawn as a curve.
Everything the layout places lands on the 20 px layout grid, whatever the editor's
**Grid size** is.
## See also
- [Editor tools for browser agents](/editor/browser-agents) — `inspect_node_layout`,
`beautify_node` and `beautify_layout` as agent tools.
- [The AI Assistant](/editor/ai-assistant) — the **AI Assistant Layout Changes**
opt-out.