Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
mindmorass avatar

Graphviz Diagrams

  • 47 installs
  • 2 repo stars
  • Updated February 12, 2026
  • mindmorass/reflex

Helps with ai & agent building tasks.

About

graphviz-diagrams is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.

  • graphviz-diagrams
  • AI & Agent Building
  • AI-coding skill

Graphviz Diagrams by the numbers

  • 47 all-time installs (skills.sh)
  • +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #7,487 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mindmorass/reflex --skill graphviz-diagrams

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs47
repo stars2
Last updatedFebruary 12, 2026
Repositorymindmorass/reflex

What it does

Helps with ai & agent building tasks.

Files

SKILL.mdMarkdownGitHub ↗

Graphviz Diagrams Skill

Purpose

Create complex graph visualizations using Graphviz DOT language, with both source code and pre-rendered images.

When to Use

  • Complex dependency graphs
  • Call graphs and code flow
  • Network topologies
  • Hierarchical structures
  • State machines with complex transitions
  • Any graph needing precise layout control

Output Format

Every Graphviz diagram should include: 1. Inline DOT source - For reference and future editing 2. Pre-rendered image - For viewing in any markdown renderer

Document Structure

~~~markdown

Diagram: [Name]

Source

digraph G {
    A -> B
}

Rendered

!Diagram Name ~~~

Rendering Workflow

Step 1: Write DOT Source

dot_source = """
digraph G {
    rankdir=LR;
    A -> B -> C;
}
"""

Step 2: Render to Image

import subprocess
from pathlib import Path

def render_graphviz(
    dot_source: str,
    output_path: Path,
    format: str = "png",
    engine: str = "dot"
) -> Path:
    """
    Render DOT source to image file.

    Args:
        dot_source: DOT language source code
        output_path: Output file path (without extension)
        format: Output format (png, svg, pdf)
        engine: Layout engine (dot, neato, fdp, circo, twopi, sfdp)

    Returns:
        Path to rendered image
    """
    output_file = output_path.with_suffix(f".{format}")

    result = subprocess.run(
        [engine, f"-T{format}", "-o", str(output_file)],
        input=dot_source,
        text=True,
        capture_output=True
    )

    if result.returncode != 0:
        raise RuntimeError(f"Graphviz error: {result.stderr}")

    return output_file

Step 3: Embed in Markdown

def create_diagram_markdown(
    name: str,
    dot_source: str,
    image_path: str
) -> str:
    """Create markdown with both source and rendered image."""
    return f"""## Diagram: {name}

### Source

{dot_source}


### Rendered
![{name}]({image_path})
"""

DOT Language Reference

Basic Graph Types

Directed Graph (digraph)
digraph G {
    A -> B;
    B -> C;
    A -> C;
}
Undirected Graph (graph)
graph G {
    A -- B;
    B -- C;
    A -- C;
}

Graph Attributes

digraph G {
    // Graph attributes
    rankdir=LR;           // Direction: TB, BT, LR, RL
    splines=ortho;        // Edge style: line, polyline, curved, ortho, spline
    nodesep=0.5;          // Space between nodes
    ranksep=1.0;          // Space between ranks
    bgcolor="white";      // Background color
    fontname="Helvetica"; // Font for labels

    // Nodes and edges
    A -> B;
}

Node Attributes

digraph G {
    // Node defaults
    node [shape=box, style=filled, fillcolor=lightblue];

    // Individual node styling
    A [label="Start", shape=ellipse, fillcolor=green];
    B [label="Process
Data", shape=box];
    C [label="Decision", shape=diamond, fillcolor=yellow];
    D [label="End", shape=ellipse, fillcolor=red];

    A -> B -> C;
    C -> D;
}
Common Node Shapes
ShapeUse Case
boxProcess, action
ellipseStart/end, terminal
diamondDecision
circleState
recordStructured data
MrecordRounded record
cylinderDatabase
folderDirectory/collection
componentComponent
noteAnnotation

Edge Attributes

digraph G {
    // Edge defaults
    edge [color=gray, fontsize=10];

    A -> B [label="step 1", color=blue, penwidth=2];
    B -> C [label="step 2", style=dashed];
    C -> D [label="step 3", arrowhead=empty];
    D -> A [label="loop", style=dotted, constraint=false];
}
Arrow Styles
ArrowheadDescription
normalFilled triangle (default)
emptyOpen triangle
dotFilled circle
odotOpen circle
diamondFilled diamond
noneNo arrowhead
veeV-shape
boxFilled square

Subgraphs and Clusters

digraph G {
    // Cluster (named subgraph with cluster_ prefix)
    subgraph cluster_frontend {
        label="Frontend";
        style=filled;
        fillcolor=lightgray;

        UI -> Components -> State;
    }

    subgraph cluster_backend {
        label="Backend";
        style=filled;
        fillcolor=lightyellow;

        API -> Service -> Database;
    }

    // Cross-cluster edges
    State -> API [label="HTTP"];
}

Records (Structured Nodes)

digraph G {
    node [shape=record];

    user [label="User|{id: int|name: string|email: string}"];
    order [label="Order|{id: int|user_id: int|total: decimal}"];

    user -> order [label="1:N"];
}

HTML Labels

digraph G {
    node [shape=none];

    table [label=<
        <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0">
            <TR><TD BGCOLOR="lightblue"><B>User</B></TD></TR>
            <TR><TD ALIGN="LEFT">id: int</TD></TR>
            <TR><TD ALIGN="LEFT">name: string</TD></TR>
            <TR><TD ALIGN="LEFT">email: string</TD></TR>
        </TABLE>
    >];
}

Layout Engines

EngineBest ForDescription
dotHierarchiesDirected graphs, trees, DAGs
neatoNetworksUndirected graphs, spring model
fdpLarge networksForce-directed, scalable
sfdpVery largeMultiscale force-directed
circoCircularCircular layouts
twopiRadialRadial layouts from root

Usage

# Different engines produce different layouts
dot -Tpng graph.dot -o graph-hierarchical.png
neato -Tpng graph.dot -o graph-spring.png
circo -Tpng graph.dot -o graph-circular.png

Common Patterns

Dependency Graph

digraph Dependencies {
    rankdir=BT;
    node [shape=box, style=filled, fillcolor=lightblue];

    // Packages
    app [label="app"];
    api [label="api"];
    core [label="core"];
    utils [label="utils"];
    db [label="database"];

    // Dependencies (arrows point to dependency)
    app -> api;
    app -> core;
    api -> core;
    api -> db;
    core -> utils;
    db -> utils;
}

State Machine

digraph StateMachine {
    rankdir=LR;
    node [shape=circle];

    // Start state
    start [shape=point, width=0.2];

    // States
    idle [label="Idle"];
    loading [label="Loading"];
    success [label="Success", shape=doublecircle];
    error [label="Error"];

    // Transitions
    start -> idle;
    idle -> loading [label="fetch()"];
    loading -> success [label="200 OK"];
    loading -> error [label="error"];
    error -> idle [label="retry()"];
    success -> idle [label="reset()"];
}

Call Graph

digraph CallGraph {
    rankdir=TB;
    node [shape=box, fontname="Courier"];

    main [style=filled, fillcolor=lightgreen];
    main -> init;
    main -> process;
    main -> cleanup;

    init -> loadConfig;
    init -> connectDB;

    process -> validateInput;
    process -> transform;
    process -> save;

    transform -> normalize;
    transform -> enrich;

    save -> connectDB [style=dashed, label="reuse"];
}

Network Topology

graph Network {
    layout=neato;
    overlap=false;
    node [shape=box];

    // Nodes
    internet [shape=cloud, label="Internet"];
    firewall [shape=box3d, label="Firewall"];
    lb [label="Load
Balancer"];
    web1 [label="Web 1"];
    web2 [label="Web 2"];
    app1 [label="App 1"];
    app2 [label="App 2"];
    db [shape=cylinder, label="Database"];

    // Connections
    internet -- firewall;
    firewall -- lb;
    lb -- web1;
    lb -- web2;
    web1 -- app1;
    web1 -- app2;
    web2 -- app1;
    web2 -- app2;
    app1 -- db;
    app2 -- db;
}

Entity Relationship

digraph ERD {
    rankdir=LR;
    node [shape=record, fontname="Helvetica"];
    edge [arrowhead=none];

    user [label="<pk> User|id: PK\lname: string\lemail: string\l"];
    order [label="<pk> Order|id: PK\luser_id: FK\ltotal: decimal\l"];
    item [label="<pk> OrderItem|id: PK\lorder_id: FK\lproduct_id: FK\l"];
    product [label="<pk> Product|id: PK\lname: string\lprice: decimal\l"];

    user:pk -> order:pk [label="1:N", arrowhead=crow];
    order:pk -> item:pk [label="1:N", arrowhead=crow];
    product:pk -> item:pk [label="1:N", arrowhead=crow];
}

Flowchart

digraph Flowchart {
    rankdir=TB;
    node [fontname="Helvetica"];

    start [shape=ellipse, label="Start", style=filled, fillcolor=lightgreen];
    input [shape=parallelogram, label="Get Input"];
    validate [shape=diamond, label="Valid?"];
    process [shape=box, label="Process Data"];
    error [shape=box, label="Show Error", style=filled, fillcolor=lightyellow];
    output [shape=parallelogram, label="Output Result"];
    end [shape=ellipse, label="End", style=filled, fillcolor=lightcoral];

    start -> input;
    input -> validate;
    validate -> process [label="Yes"];
    validate -> error [label="No"];
    error -> input;
    process -> output;
    output -> end;
}

Integration with Publishers

Obsidian Integration

def publish_graphviz_to_obsidian(
    vault_path: str,
    folder: str,
    filename: str,
    diagram_name: str,
    dot_source: str
):
    """Publish Graphviz diagram to Obsidian with source and image."""
    from pathlib import Path

    vault = Path(vault_path)
    target_dir = vault / folder
    attachments_dir = vault / "attachments"

    target_dir.mkdir(parents=True, exist_ok=True)
    attachments_dir.mkdir(parents=True, exist_ok=True)

    # Render image
    image_name = f"{filename}-diagram.png"
    image_path = attachments_dir / image_name
    render_graphviz(dot_source, image_path.with_suffix(""), "png")

    # Create markdown with both source and image
    content = f"""# {diagram_name}

## Source

{dot_source}


## Rendered

![[{image_name}]]
"""

    note_path = target_dir / f"{filename}.md"
    note_path.write_text(content)

Joplin Integration

def publish_graphviz_to_joplin(
    notebook: str,
    title: str,
    diagram_name: str,
    dot_source: str
):
    """Publish Graphviz diagram to Joplin with source and image."""
    import tempfile
    from pathlib import Path

    with tempfile.TemporaryDirectory() as tmpdir:
        tmpdir = Path(tmpdir)

        # Render image
        image_path = tmpdir / "diagram.png"
        render_graphviz(dot_source, image_path.with_suffix(""), "png")

        # Create markdown
        content = f"""# {diagram_name}

## Source

{dot_source}


## Rendered

![{diagram_name}](./diagram.png)
"""

        md_path = tmpdir / f"{title}.md"
        md_path.write_text(content)

        # Import to Joplin (imports markdown and referenced images)
        subprocess.run([
            "joplin", "import", str(tmpdir),
            "--notebook", notebook
        ], check=True)

Graphviz vs Mermaid

FeatureGraphvizMermaid
Layout controlPrecise, many enginesAutomatic only
ComplexityHandles very large graphsBetter for simpler diagrams
RenderingExternal tool requiredBrowser-native
StylingExtensive optionsLimited but sufficient
Learning curveSteeperEasier
Use caseComplex dependencies, call graphsQuick diagrams, sequences

Use Graphviz when:

  • You need precise layout control
  • Graph is large or complex
  • You need specific node arrangements
  • Creating dependency or call graphs

Use Mermaid when:

  • Quick inline diagrams
  • Sequence diagrams
  • Simple flowcharts
  • Native browser rendering preferred

Prerequisites

Install Graphviz

# macOS
brew install graphviz

# Ubuntu/Debian
sudo apt-get install graphviz

# Windows (chocolatey)
choco install graphviz

# Verify installation
dot -V

Checklist

Before creating Graphviz diagrams:

  • [ ] Graphviz installed (dot -V)
  • [ ] Output directory writable
  • [ ] DOT syntax validated
  • [ ] Appropriate layout engine selected
  • [ ] Both source and image included in output
  • [ ] Image path correct for target (Obsidian/Joplin)

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.