
Diagram To Image
Render Mermaid diagrams or markdown tables to PNG from the terminal for READMEs, specs, and launch assets.
Overview
Diagram to Image is an agent skill most often used in Build (also Launch, Grow) that converts Mermaid or markdown tables into themed PNGs via a CLI and remote render server.
Install
npx skills add https://github.com/sugarforever/01coder-agent-skills --skill diagram-to-imageWhat is this skill?
- Node CLI: diagram-to-image with required -o PNG output
- Auto-detects mermaid vs table via --type auto|mermaid|table
- 10 named themes (default, dark, forest, neutral, ocean, emerald, midnight, slate, lavender, blueprint)
- Scale factor 1–4 (default 2) and optional --bg background color
- Remote render default server https://diagramless.xyz with --server override
- 10 named render themes
- Scale factor range 1–4 (default 2)
Adoption & trust: 1 installs on skills.sh; 116 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your docs use Mermaid or tables but social, PDF, and README viewers need static images and manual screenshots waste time.
Who is it for?
Indie builders automating README diagrams, architecture figures, and table snapshots with a one-command Node CLI.
Skip if: Interactive diagram editing, offline-only air-gapped renders without a server, or proprietary diagram formats beyond mermaid/table.
When should I use this skill?
You need a PNG from a Mermaid diagram or markdown table via CLI, optionally themed and scaled for docs or distribution.
What do I get? / Deliverables
You get a scaled PNG on disk from a file or pipe, with theme and type flags repeatable in scripts and CI.
- PNG image at the specified -o output path
- Scriptable diagram export suitable for docs and CI
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Diagram exports are created most often while documenting the product, but the same CLI supports launch and grow content pipelines. Docs is the primary shelf because the tool turns text diagrams into shareable images for repositories and guides.
Where it fits
Batch-render sequence diagrams from *.mmd into PNGs before tagging a release README.
Generate neutral-theme figures for a Product Hunt gallery or blog post that blocks live Mermaid.
Re-export onboarding flowcharts with the ocean theme after updating copy in markdown tables.
How it compares
CLI wrapper around a render API—not an in-editor Mermaid preview or Figma replacement.
Common Questions / FAQ
Who is diagram-to-image for?
Developers and technical writers who live in the terminal and want PNG exports from Mermaid or markdown tables for docs and marketing.
When should I use diagram-to-image?
Use it in Build/docs for repo diagrams; in Launch/distribution for shareable figures; in Grow/content when refreshing tutorial or changelog images.
Is diagram-to-image safe to install?
The CLI sends diagram source to a configurable remote server by default—do not pipe secrets; review the Security Audits panel on this page and prefer a self-hosted --server for sensitive diagrams.
SKILL.md
READMESKILL.md - Diagram To Image
#!/usr/bin/env node import { readFileSync, writeFileSync } from 'node:fs'; const DEFAULTS = { server: 'https://diagramless.xyz', scale: 2, type: 'auto', theme: 'default', }; function usage() { console.log(`Usage: diagram-to-image [input-file] -o <output.png> [options] Options: -o, --output <file> Output PNG file (required) --theme <name> Theme: default, dark, forest, neutral, ocean, emerald, midnight, slate, lavender, blueprint --type <type> Content type: auto, mermaid, table (default: auto) --scale <n> Scale factor 1-4 (default: 2) --bg <color> Background color (default: white) --server <url> Server URL (default: ${DEFAULTS.server}) -h, --help Show this help Examples: diagram-to-image diagram.mmd -o output.png diagram-to-image table.md -o table.png --type table --theme ocean echo "graph TD; A-->B" | diagram-to-image -o out.png`); process.exit(0); } // Parse args const args = process.argv.slice(2); if (args.length === 0 || args.includes('-h') || args.includes('--help')) usage(); let inputFile = null; let output = null; let theme = DEFAULTS.theme; let type = DEFAULTS.type; let scale = DEFAULTS.scale; let bg = 'white'; let server = DEFAULTS.server; for (let i = 0; i < args.length; i++) { const arg = args[i]; if (arg === '-o' || arg === '--output') { output = args[++i]; } else if (arg === '--theme') { theme = args[++i]; } else if (arg === '--type') { type = args[++i]; } else if (arg === '--scale') { scale = Number(args[++i]); } else if (arg === '--bg') { bg = args[++i]; } else if (arg === '--server') { server = args[++i]; } else if (!arg.startsWith('-')) { inputFile = arg; } else { console.error(`Unknown option: ${arg}`); process.exit(1); } } if (!output) { console.error('Error: -o/--output is required'); process.exit(1); } // Read input from file or stdin let code; if (inputFile) { code = readFileSync(inputFile, 'utf-8'); } else if (!process.stdin.isTTY) { code = readFileSync(0, 'utf-8'); } else { console.error('Error: provide an input file or pipe content via stdin'); process.exit(1); } // POST to server const url = `${server}/api/render`; const body = JSON.stringify({ code, theme, type, scale, bg }); try { const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body, }); if (!res.ok) { const err = await res.json().catch(() => ({ error: res.statusText })); console.error(`Error ${res.status}: ${err.error || res.statusText}`); process.exit(1); } const buffer = Buffer.from(await res.arrayBuffer()); writeFileSync(output, buffer); console.log(`Saved ${output} (${buffer.length} bytes)`); } catch (err) { console.error(`Failed to connect to ${url}: ${err.message}`); console.error('Is the diagramless.xyz server reachable?'); process.exit(1); } #!/usr/bin/env python3 """ Convert Markdown table to PNG image. Usage: python3 table_to_image.py <input.md> <output.png> [--scale 2] """ import sys import re from pathlib import Path try: from PIL import Image, ImageDraw, ImageFont except ImportError: print("Error: Pillow not installed. Run: pip install pillow") sys.exit(1) def parse_markdown_table(content: str) -> tuple[list[str], list[list[str]], list[str]]: """Parse markdown table into headers, rows, and alignments.""" lines = [line.strip() for line in content.strip().split('\n') if line.strip()] if len(lines) < 2: raise ValueError("Table must have at least 2 rows") def parse_cells(line: str) -> list[str]: line = line.strip() if line.startswith('|'): line = line[1:] if line.endswith('|'): line = line[:-1] return [cell.strip() for cell in line.split('|')] # Find separator line separator_idx = -1 for i, line in enumerate(lines): if re.match(r'^\|?[\s]*:?-{2,}:?[\s]*(\|[\s]*:?-{2,}:?[\s]*)*\|?$', line):