Most internal flowchart tools die the same way. Someone sketches the support escalation process, screenshots it into a Confluence page, and the page lives forever. A year later the routing has changed, the diagram still shows the old flow, nobody owns the original file, and nobody opens the flowchart tool anyway because it's faster to write a paragraph than to fight the editor.
The Process Mapper module in FreeITSM started in the same place — a basic drag-and-drop builder for boxes and arrows. Useful for a sketch. Not enough to be the source of truth.
Three feature waves later it's something different. This piece walks through each of those waves and why each one matters.
The thing a process documentation tool actually has to do is survive the next edit. Someone needs to open it six months from now, change one box, and walk away feeling like the diagram improved — not feeling like they just wrestled the editor for fifteen minutes to move three things around.
A flowchart tool earns the right to stay open by making each edit feel cheaper than rewriting the diagram from scratch.
The four waves below all serve that same goal. They're not random features — each one removes a specific reason an analyst might give up halfway through an edit and reach for a screenshot instead.
Wave one: stop losing work
The single most-broken thing about lightweight diagram tools is that you have to remember to save. Move three boxes, refine a label, tab away to check a ticket, come back, accidentally hit refresh — everything since the last manual save is gone.
The first wave fixes that. There's an Autosave toggle in the toolbar that persists per-analyst — tick it once and it stays ticked for you across sessions, devices, and browsers. With autosave on, a debounced save fires about two seconds after the last edit. Debounced rather than continuous: if you're actively dragging a step around or typing into a label, the timer keeps resetting, so it only fires when you've actually paused. No partial captures of half-finished interactions, no wasted writes on a diagram that you're just panning around without changing.
Beside the toggle there's a live status indicator that shows you exactly what state your work is in:
The same idiom Microsoft Word uses, for the same reason: most of the time the indicator is reading Saved in a calm green and you stop thinking about persistence at all. The brief flash to Saving… is held visible for at least 400ms so it doesn't just blink, which makes the system feel honest about what it's doing. A failed save surfaces as an amber retry link rather than a silent failure, so you find out immediately.
The subtle bit is what autosave doesn't do. It doesn't fire mid-drag. Earlier versions had a problem where the autosave timer would occasionally land during a drag interaction — the save would reload the canvas with fresh real IDs from the server, and that reload would destroy the in-progress element you were dragging. So you'd see the detail panel slide closed and the step snap back to its last-committed position partway through your drag. Now the autosave timer checks for any active drag state when it fires (steps, groups, lanes, rubber-band selection, connector drawing) and defers itself until the mouse is released.
And the detail panel survives autosave too. Previously every autosave reload closed the panel, so if you were editing a step's properties when the save fired, the form you were filling in would slide shut every couple of seconds. Now the system captures your current selection by stable identity (a step's x/y, a group's x/y/width/height, a lane's display_order) before each save, then re-finds the equivalent entity after the reload picks up fresh real IDs and re-populates the panel transparently. Edit, autosave, keep editing. The save becomes invisible.
Wave two: visual grouping
Once you've got more than half a dozen boxes on the canvas, you need a way to say "this cluster of steps is the triage phase" or "these three are all part of the resolution work". The natural answer is a group: a labelled coloured rectangle that sits behind the steps as a visual underlay.
Click the Group button in the toolbar to drop one at the canvas centre. Drag to move, drag the bottom-right corner to resize, double-click to rename. Groups snap to the 20px grid like everything else, and they render behind connectors and steps so the foreground stays legible.
The thing that makes groups actually useful, though, is that they own their contents. Drop a step inside a group and the step picks up a group_id pointer to that group. Drag the group around the canvas and every step inside comes with it — the group becomes a container, not just an underlay. Resize the group smaller until a step's centre falls outside the rectangle and that step's group_id clears automatically on mouseup. The data model and the visual model stay in agreement.
When groups overlap (you can draw an inner group inside a wider outer one to highlight a sub-flow), the smallest group wins for ownership. The intuition is that the smaller rectangle is the more specific claim about what a step belongs to. A step that sits inside both a big "Production support" group and a smaller "P1 escalation" group inside it goes with the P1 escalation group when you drag.
Crucially, groups don't enforce a stack. You can draw them anywhere, any size, overlapping or not, and steps can live in zero, one, or several groups. They're additive overlays for the cases where lanes (next section) would be too rigid.
Wave three: swimlanes
Some processes have a natural structure that groups can't capture cleanly: a handoff between teams. A new-hire onboarding flow has steps that belong to HR, steps that belong to IT, steps that belong to the manager, and the value of the diagram is largely about showing the handoffs. Same with incident escalation (L1 → L2 → L3 → vendor) or change approval (requester → CAB → implementer → reviewer).
For these flows you want swimlanes: horizontal bands stacked across the canvas, one per role/team/department, with steps belonging to exactly one lane and connectors crossing lane boundaries to show the handoff. It's a different concept from a group — structured rather than free-form, exclusive rather than additive, stacked rather than placed.
Here's what the lane stack looks like for a simple onboarding flow:
Click Lane in the toolbar to add a band at the bottom of the stack. Click the lane's left-edge header to select it; type a name in the detail panel and it shows up vertically along the left edge. Drag the header up or down to reorder — the lane snaps between slots as the cursor crosses each neighbour's midline, and every step in every affected lane reflows automatically to stay anchored to its own band.
That reflow is the trick that makes swimlanes actually work. The naive implementation is "lanes stack from top to bottom in display order, and a step's lane_id tells you which lane it belongs to". Easy enough. But the moment you let someone drag a lane to reorder, you have to decide what happens to the steps inside — and the only answer that doesn't feel broken is "they move with their lane".
So before the swap, the system snapshots every step's offset within its current lane (the step's y minus its lane's bandTop). After the swap, lane band positions recompute, and each step's y is rewritten to its lane's new bandTop plus its preserved offset. A step that was 20px from the top of its lane stays 20px from the top of its lane after the lane moves to a new slot. Same logic works for groups inside lanes — their containing lane is derived on the fly from each group's vertical centre, since groups don't have a stored lane_id, but the rest of the snapshot/reapply machinery is identical.
Resize a lane by dragging its bottom edge. The divider locks to the 20px grid (otherwise it would drift smoothly while the contents inside lurch in 20px snap increments). Every step and group visually below the divider shifts by the same delta, so the bands below stay anchored to their contents.
Steps gain a nullable lane_id that auto-assigns based on where the step ends up after each drag. Drop a step into a lane band and on mouseup the step picks up that lane's id. Drop it outside every lane and lane_id clears. Delete a lane and contained steps lose their assignment but keep their position — nothing is lost, just untagged.
Steps without a lane_id still work normally. Not every process needs lanes. The feature is opt-in: a diagram with no lanes behaves exactly as it did before.
Wave four: stop hoarding the diagram
You've built the diagram. You're proud of it. It lives in FreeITSM. So does your documentation? Probably not — your runbooks live in GitHub, your team docs in Notion, your service catalogue on Confluence. The flowchart can be perfect and still be irrelevant if nobody opens FreeITSM to look at it.
The fix is the Export button in the toolbar. Click it and you get a modal with the current diagram rendered as Mermaid markup, ready to paste into any Markdown surface that supports it — GitHub READMEs and wikis, Notion (via a /mermaid block), Confluence, Obsidian, the Mermaid Live Editor, or back into your own FreeITSM wiki.
The structure translates faithfully. Lanes become subgraph blocks — the conventional idiom for swimlanes in Mermaid flowcharts. With flowchart LR direction the subgraphs stack vertically and read exactly like the lanes you drew. Each shape type gets the corresponding Mermaid syntax. Connectors become arrows with their labels surviving as quoted strings, and Mermaid resolves IDs across subgraph boundaries so cross-lane handoffs render naturally without any special handling.
A small lane diagram exports to:
flowchart LR
subgraph lane1["HR"]
s1["Receive request"]
s2["Verify"]
end
subgraph lane2["IT"]
s3["Provision"]
end
subgraph lane3["Manager"]
s4{"Approve?"}
end
s1 --> s2
s2 --> s3
s3 --> s4
s4 -->|"Yes"| s5(["Complete"])
s4 -->|"No"| s6[/"Reject doc"/]
What doesn't survive is the visual styling. Mermaid auto-layouts, so your hand-placed step positions get replaced by Mermaid's algorithm; gradient fills don't translate; group rectangles don't translate (Mermaid only has subgraphs, which we're already using for lanes). It's a lossy on visuals, faithful on structure export. The meaning of the diagram — what steps exist, what flows where, which lane each step is in — comes through perfectly.
And that's the right trade. Most documentation surfaces have their own house style; a Mermaid render in your GitHub wiki should look like every other Mermaid diagram in your GitHub wiki, not like a screenshot from a different tool. Lossy is what makes it portable.
The connectors-for-free moment
One thing worth calling out because it surprised me too when it landed. Connectors in the Process Mapper aren't stored with positions — they're stored as {from_step_id, to_step_id} only. At every render, the endpoints get computed from whichever step coordinates are current.
The visible side-effect is that when you reorder a lane and the steps inside it slide down to follow their lane to its new slot, connectors crossing between lanes re-route automatically. There's no special handling for cross-lane arrows, no "redraw connectors on lane move" code. The data model just doesn't carry redundant position information, so the rendering pass always agrees with the steps' current positions.
It's the kind of behaviour that takes ten minutes to add up front and a week to retro-fit. Worth the foresight.
What's earned, what's left
Taken together, the four waves remove the four specific reasons a documentation diagram tends to get abandoned:
Lose your work
Autosave with status indicator and drag-aware deferral. Edit, walk away, come back — it's saved.
No structure
Groups for free-form clusters, swimlanes for role-based handoffs. Each composes with the other, both opt-in.
Fighting the editor
Snap-to-grid everything, dragging that carries ownership semantically, detail panel that survives reload.
Trapped in the tool
Mermaid export so the diagram lives in your documentation surface, not just in the editor.
The bits that aren't there yet: there's no live Mermaid preview inside the export modal (you copy and paste into your destination to see the render), no vertical-lane orientation (lanes are horizontal-only), no nested swimlanes, no auto-layout button for arranging an existing process. Each of those is an obvious next step and none of them blocks today's use case.
The point of process modelling, in the end, isn't producing a beautiful diagram once. It's producing one that gets opened and edited a year from now, by someone different to the person who drew it, who walks away with a slightly more correct picture of how the work really happens. Every feature above is in service of that.