___________________________________________________________
| |
| _____ _ ______ _ |
| | __ \ | | | ____| | |
| | |__) |___| |_ _ __ ___ | |__ | | _____ __ |
| | _ // _ \ __| '__/ _ \| __| | |/ _ \ \ /\ / / |
| | | \ \ __/ |_| | | (_) | | | | (_) \ V V / |
| |_| \_\___|\__|_| \___/|_| |_|\___/ \_/\_/ |
| |
| [ Beautiful ASCII Flowcharts ] |
|___________________________________________________________|
|| ||
A Python library for generating beautiful ASCII and PNG flowcharts from simple text descriptions.
This is a project to help engineers, researchers, project managers, and others create beautiful, retro-looking ASCII flow diagrams. ASCII diagrams are pretty, and harken back to the mid-20th century technical documentation. They also have real advantages:
- They work wonderfully in the age of agentic AI, which can easily read and parse these small representations.
- ASCII diagrams can live inline with: PRs, Markdown files, Slack threads, etc.
- ASCII diagrams optimize for thinking speed, not presentation quality. It encourages iteration and deletion instead of premature refinement.
- Minimalist diagrams reduce visual noise (although they do still look retro and pretty)
- They're tool agnostic and can be rendered anywhere
╔════════╗
║ Mesh ║
╚════════╝
┌──────────────────────────────────────────────────────────────────────────────────────┐
│ │
│ │
│ ┌────────────────────────────────────┐
│ │ │
│ │ │
│ ┌────────────────────────┼───────────┐ │
│ │ │ │ │
│ │ │ │ │
│┌───────────────────────┼───────────┐ │ │ │
││ │ │ │ │ │
││ │ │ │ │ │
││ │ │ │ │ │
▼▼ ▼ │ ▼ │ │
┌──────────┐ ┌──────────┐ │ ┌──────────┐ │ ┌──────────┐ │
│ ┤────────────►│ ┤─┘ │ ┤─┘ │ ┤─┘
│ Node A ┤──────┐ │ Node B ┤────────────►│ Node C ┤──────┌─────►│ Node D │░
│ │░ │ │ │░ │ │░ │ │ │░
└──────────┘░ │ └──────────┘░ └──────────┘░ │ └──────────┘░
░░░░░░░░░░░░ │ ░░░░░░░░░░░░ ░░░░░░░░░░░░ │ ░░░░░░░░░░░░
│ │
│ │
│ │
└─────────────────────────────────────────────────┘
pip install retroflowOr with uv:
uv add retroflowfrom retroflow import FlowchartGenerator
# Create a generator
generator = FlowchartGenerator()
# Define your flowchart using simple arrow syntax
flowchart = generator.generate("""
Start -> Process
Process -> Decision
Decision -> End
""")
print(flowchart)- Simple syntax: Define flowcharts using intuitive
A -> Barrow notation - ASCII output: Generate text-based flowcharts for terminals and documentation
- PNG export: Save high-resolution PNG images with customizable fonts
- Intelligent layout: Automatic node positioning using NetworkX with barycenter heuristic
- Smart edge routing: Edges automatically route around intermediate boxes to avoid visual overlap
- Cycle detection: Handles cyclic graphs gracefully with back-edge routing
- Customizable: Adjust text width, box sizes, spacing, shadows, and fonts
- Unicode box-drawing: Beautiful boxes with optional shadow effects
- Title banners: Optional double-line bordered titles with automatic word wrapping
- Horizontal flow: Left-to-right layout mode for compact linear diagrams
- Group boxes: Experimental, visually cluster related nodes within dashed-border containers with titles
from retroflow import FlowchartGenerator
generator = FlowchartGenerator()
# Simple linear flow
result = generator.generate("""
A -> B
B -> C
C -> D
""")
print(result)# Branching and merging
result = generator.generate("""
Start -> Validate
Validate -> Process
Validate -> Error
Process -> End
Error -> End
""")
print(result)# Loops and cycles are supported
result = generator.generate("""
Init -> Check
Check -> Process
Process -> Check
Check -> Done
""")
print(result)generator = FlowchartGenerator()
generator.save_txt("""
A -> B
B -> C
""", "flowchart.txt")Save your flowchart as a high-resolution PNG image:
generator = FlowchartGenerator()
generator.save_png("""
A -> B
B -> C
""", "flowchart.png")Customize the PNG output with various options:
generator.save_png(
"A -> B\nB -> C",
"flowchart.png",
font_size=24, # Base font size in points (default: 16)
bg_color="#1a1a2e", # Background color (default: "#FFFFFF")
fg_color="#00ff00", # Text color (default: "#000000")
padding=40, # Padding around diagram in pixels (default: 20)
scale=2, # Resolution multiplier for crisp output (default: 2)
)The scale parameter controls the output resolution. With the default scale=2, images render at 2x resolution for crisp display on high-DPI/retina screens. Use scale=1 for smaller file sizes, or scale=3 for even sharper output.
generator = FlowchartGenerator(
max_text_width=22, # Max width for text inside boxes before wrapping (default: 22)
min_box_width=10, # Minimum box width (default: 10)
horizontal_spacing=12, # Space between boxes horizontally (default: 12)
vertical_spacing=6, # Space between boxes vertically (default: 6)
shadow=True, # Whether to draw box shadows (default: True)
font="Cascadia Code", # Font for PNG output (default: None, uses system font)
title="My Diagram", # Optional title banner with double-line border (default: None)
direction="TB", # Flow direction: "TB" (top-to-bottom) or "LR" (left-to-right)
)You can specify a font for PNG output either at initialization or per-call:
# Set font for all PNG exports from this generator
generator = FlowchartGenerator(font="Cascadia Code")
generator.save_png("A -> B", "flowchart.png")
# Or override the font for a specific export
generator.save_png("A -> B", "flowchart.png", font="Monaco")Common monospace fonts that work well:
- Windows:
Cascadia Code,Consolas,Courier New - macOS:
Monaco,Menlo,SF Mono - Linux:
DejaVu Sans Mono,Ubuntu Mono,Liberation Mono
If the specified font isn't found, RetroFlow automatically falls back to available system fonts.
Add a title banner with a double-line border above your flowchart:
generator = FlowchartGenerator(title="CI/CD Pipeline")
result = generator.generate("""
Build -> Test
Test -> Deploy
""")Output:
╔══════════════════╗
║ CI/CD Pipeline ║
╚══════════════════╝
┌─────────┐
│ Build │░
└────┬────┘░
░░░░│░░░░░░
│
▼
┌─────────┐
│ Test │░
└────┬────┘░
░░░░│░░░░░░
│
▼
┌──────────┐
│ Deploy │░
└──────────┘░
░░░░░░░░░░░░
Title Wrapping: Long titles automatically wrap at word boundaries (approximately every 15 characters) to keep the title box compact:
generator = FlowchartGenerator(title="My Very Long Project Title Here")╔═════════════════╗
║ My Very Long ║
║ Project Title ║
║ Here ║
╚═════════════════╝
You can also override the title per-call:
generator.generate("A -> B", title="Override Title")Use direction="LR" for left-to-right layouts instead of top-to-bottom:
generator = FlowchartGenerator(direction="LR")
result = generator.generate("""
Start -> Process
Process -> End
""")This produces a horizontal flowchart where nodes flow from left to right, which can be more compact for linear processes.
Group boxes let you visually cluster related nodes together within a labeled container. This is useful for showing subsystems, modules, or logical groupings.
Group boxes work well as long as your diagram is complex, with several groups and fully-connected nodes.
Define groups at the top of your input, before edge definitions:
generator = FlowchartGenerator()
result = generator.generate("""
[API Layer: Gateway Auth]
[Data Layer: Database Cache]
Gateway -> Auth
Auth -> Database
Database -> Cache
Gateway -> Cache
""")
print(result)Syntax: [GROUP TITLE: node1 node2 node3]
- Text before the colon is the group title (displayed above the group box)
- Text after the colon is a space-separated list of node names
- Multi-word node names work automatically (matched against nodes in edges)
Example output:
API LAYER
┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐
┆ ┆░
┆ ┌───────────┐ ┆░
┆ │ Gateway │░ ┆░
┆ └───────────┘░ ┆░
┆ ░░░░░░░░░░░░ ┆░
┆ │ ┆░
┆ ▼ ┆░
┆ ┌───────────┐ ┆░
┆ │ Auth │░ ┆░
┆ └───────────┘░ ┆░
┆ ░░░░░░░░░░░░ ┆░
└┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘░
░░░░░░░░░░░░░░░░░░░░░
Rules:
- Each node can belong to at most one group
- Group definitions must appear before any edge definitions
- Nodes within groups are arranged perpendicular to the flow direction (horizontally in TB mode, vertically in LR mode)
The input format uses a simple arrow syntax:
# Optional: Group definitions (must come first)
[Frontend: Login Dashboard]
[Backend: API Database]
# Comments start with #
NodeA -> NodeB
NodeB -> NodeC
# Node names can contain spaces
User Login -> Validate Credentials
Validate Credentials -> Access Granted
- Each line defines one connection:
Source -> Target - Node names are trimmed of whitespace
- Empty lines are ignored
- Lines starting with
#are comments - Node names can contain spaces
- Group definitions use
[Group Name: node1 node2]syntax and must appear before edges
The main class for generating flowcharts.
| Method | Description |
|---|---|
generate(input_text) |
Generate ASCII flowchart string |
save_txt(input_text, filename) |
Save flowchart to a text file |
save_png(input_text, filename, ...) |
Save flowchart as a PNG image |
from retroflow import parse_flowchart
# Parse without rendering
connections = parse_flowchart("A -> B\nB -> C")
# Returns: [('A', 'B'), ('B', 'C')]For advanced use cases, you can access the individual components:
from retroflow import (
Parser,
SugiyamaLayout, # Alias for NetworkXLayout
Canvas,
BoxRenderer,
)
# Parse input
parser = Parser()
connections = parser.parse("A -> B\nB -> C")
# Compute layout
layout_engine = SugiyamaLayout()
layout_result = layout_engine.layout(connections)
# Access layout information
for node_name, node_layout in layout_result.nodes.items():
print(f"{node_name}: layer={node_layout.layer}, position={node_layout.position}")git clone https://github.com/ronikobrosly/retroflow.git
cd retroflow
uv sync --devuv run pytestuvx ruff check .
uvx ruff format --check .MIT License - see LICENSE for details.
Contributions are 100% welcome! Please feel free to submit a PR.

