Skip to content
github-actions[bot] edited this page Jul 23, 2026 · 2 revisions

Exporting Your Mesh

One of the great strengths of F-Mesh is its inherent traversability, making it straightforward to export the mesh into structured formats or visualize it as a graph.

Available formats and packages:

  • DOT — export the mesh as a Graphviz DOT graph.

Static graph

import "github.com/hovsep/fmesh-graphviz/dot"

exporter := dot.NewDotExporter()
graph, err := exporter.Export(fm) // []byte of DOT source
if err != nil {
    // handle error
}
_ = os.WriteFile(fm.Name()+"-graph.dot", graph, 0o644)

Component and port names, descriptions (emoji work fine), and pipes all appear in the graph — a mesh built with meaningful descriptions is self-documenting when exported.

View the result by pasting it into an online viewer such as edotor.net, or render locally with Graphviz:

dot -Tsvg mesh-graph.dot -o mesh-graph.svg
# batch-convert a directory of graphs:
for f in *.dot; do dot -Tpng "$f" -o "${f%.dot}.png"; done

Per-cycle graphs

ExportWithCycles produces one graph per activation cycle, highlighting which components activated in each — a visual replay of the run:

runtimeInfo, err := fm.Run()
// ...
cycleGraphs, err := exporter.ExportWithCycles(fm, runtimeInfo.Cycles)
for cycleNum, graph := range cycleGraphs {
    _ = os.WriteFile(fmt.Sprintf("cycle-%d.dot", cycleNum), graph, 0o644)
}

See Inspecting a run for what else RuntimeInfo holds. If a long run makes this expensive, cap the history with WithCyclesHistoryLimit — only retained cycles can be exported.

Tip: an export flag in your app

Since the mesh is fully built before it runs, a cheap pattern is to gate export behind an environment variable or CLI flag: when set, the program builds the mesh, writes the graph, and exits without running. Handy for getting a topology picture of any mesh — build first, run only when asked:

if os.Getenv("MESH_GRAPH") == "1" {
    graph, _ := dot.NewDotExporter().Export(fm)
    _ = os.WriteFile(fm.Name()+"-graph.dot", graph, 0o644)
    return
}
_, err := fm.Run()

Clone this wiki locally