app-dev/figjam-diagrams/SKILL.md
name: figjam-diagrams description: >- Layout craft for readable FigJam architecture/flow diagrams. Use whenever creating or editing a diagram in FigJam — after generate_diagram (whose auto-layout is reliably bad) or when building/rearranging nodes via use_figma. Load alongside the plugin figma-use / figma-generate-diagram skills; this one adds the layout rules and FigJam node-manipulation gotchas they don't cover.
figjam-diagrams
generate_diagram gets topology and edge labels right but layout wrong:
sprawling sections, diagonal queue chains, labels buried under shapes. Plan
for a generate → compact → verify loop, not a one-shot call. Expect 2–3
render-look-fix iterations; budget them, don't fight them.
Content before layout
- Diagram quality is bounded by context. Grep the actual repo (terraform,
handlers, queue definitions) and use real file/class/method names as node
and edge labels —
billingWebhookProcess.processEvent, not "processor". - Mark proposed/not-yet-built components
(new)inline in the label. - Don't invent edges to round out the picture; a gap beats a hallucination.
Layout rules (the ones that actually fix readability)
- One column per pipeline stage, strictly left-to-right in data-flow order (ingress → router → queues → consumers → downstream). Parallel paths become horizontal lanes sharing the same column grid — never scattered rows.
- Size each shape to its text. Long identifiers need 350–480+ width; forcing uniform small shapes causes ugly wraps and overflow. Resize per node, not globally.
- Column gaps must exceed the longest connector label living in them. FigJam renders labels at the path midpoint and you cannot move the label itself — if the gap is narrower than the label, it lands on a shape. Estimate ~9px per character at default font and leave slack.
- Reserve empty corridors for long skip-stage edges (e.g. router → datastore): route them above or below the whole grid, never threaded between columns. Give the corridor its own headroom so the label sits in pure whitespace.
- Continuation chains go to a new lane at the bottom-right, continuing the left-to-right flow, so their inbound drop edges fall through open space instead of crossing other columns.
- Keep edges orthogonal; avoid diagonals. Pin magnets when auto-routing picks a bad side (see below).
FigJam node-manipulation gotchas (use_figma)
- Placement: new generated sections land far to the right of all
existing content — after generating, read coords with
get_figjamand move the section next to the rest of the board. Deleting a section leaves its old gap; reposition survivors. - Flatten before rearranging: the architecture layout
(
FIGMA_DIAGRAM_2026) nests lane sub-sections inside the diagram section. Reparent children to the outer section (outer.appendChild(child)) beforeinner.remove()— removing a section deletes its children. - Match nodes by ID, never by name substring. Names collide hard here
(
webhook-forwardmatches both the lambda and the queue). Pull IDs fromget_figjamoutput and hardcode them in the script. - Shapes are
SHAPE_WITH_TEXT; resize withnode.resize(w, h). Generated widths are inconsistent (one shape came out 666px wide) — normalize per content, checkingnode.widthfirst. - Connectors follow moved/reparented shapes automatically — moving
shapes is always safe. To force a side:
c.connectorStart = { ...c.connectorStart, magnet: 'BOTTOM' }(reassign the whole object; in-place mutation doesn't stick). Values: AUTO, TOP, BOTTOM, LEFT, RIGHT, CENTER. - Shrink the wrapper with
section.resizeWithoutConstraints(w, h)— children keep their coordinates. - Labels can only be fixed by moving shapes or pinning magnets so the path midpoint lands in whitespace.
Verify loop
get_screenshot on the section node → curl the returned URL to the
scratchpad → Read the PNG. Check specifically for: labels clipped by shapes,
edges routing through boxes, dead whitespace bloating the section. Fix and
re-screenshot until clean, then screenshot the whole page once to confirm
placement relative to existing content.
Tool prerequisites
generate_diagramneedsplanKey(whoamilists plans — pick the org with a Full seat) and the pluginfigma-generate-diagramskill loaded first; passfileKeyto add to an existing board instead of a new draft.use_figmarequires the pluginfigma-useskill loaded first; FigJam files reject design-only APIs (figma.createPage, most design node types).
