· 5 min read

Building a GitHub Actions Workflow Visualizer


After spending too many hours debugging complex GitHub Actions workflows by reading hundreds of lines of YAML, I decided to build something better: an interactive visualizer that turns workflow files into something you can actually see and understand.

The Problem

GitHub Actions workflows are powerful, but they’re also just YAML files. When you have:

  • Multiple jobs with complex dependencies
  • Matrix strategies that create dozens of job variations
  • Reusable workflows calling other workflows
  • Conditional logic scattered throughout

…it becomes nearly impossible to understand the actual execution flow without mentally parsing the entire file.

The GitHub UI shows you job execution after the fact, but what if you want to understand the workflow before you push it?

What I Built

GitHub Actions Workflow Editor & Visualizer is a web app that does three things:

  1. Edit workflows with a full Monaco editor (same editor as VS Code)
  2. Validate in real-time with immediate feedback on syntax and structure errors
  3. Visualize dependencies as an interactive directed graph

Try it live: dcotelo.github.io/actions

Technical Architecture

The Stack

  • React for UI components
  • Monaco Editor for YAML editing with syntax highlighting
  • Dagre for graph layout calculations
  • js-yaml for parsing and validation

No backend. Everything runs in the browser.

Core Components

1. The Parser

The first challenge was extracting the dependency graph from YAML. GitHub Actions uses a needs field to declare job dependencies:

jobs:
  test:
    runs-on: ubuntu-latest
    steps: [...]
  
  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps: [...]

I built a parser that:

  • Extracts all jobs and their metadata
  • Maps needs relationships into a directed graph
  • Detects circular dependencies (which GitHub doesn’t allow)
  • Handles matrix strategies that create multiple job instances

2. The Visualizer

The graph view uses Dagre for layout calculations. Given a set of nodes and edges, Dagre figures out where to position everything to minimize edge crossings and create a clean layout.

I added:

  • Interactive highlighting: Hover over a job to see its complete dependency chain (upstream and downstream)
  • Zoom and pan controls: Middle-mouse or space+drag to navigate large workflows
  • Layout direction toggle: Switch between left-to-right and top-to-bottom layouts
  • Cycle detection warnings: Visual indicators when circular dependencies are found

3. The Validator

Real-time validation was crucial. The validator checks:

YAML syntax:

  • Valid YAML structure
  • Proper indentation
  • Quote matching

GitHub Actions structure:

  • Required fields (on, jobs, etc.)
  • Valid trigger events
  • Job structure requirements
  • Step definitions

Dependency logic:

  • All needs references point to valid jobs
  • No circular dependencies
  • No orphaned jobs

Validation errors are clickable — click an error to jump directly to the problematic line in the editor.

Handling Edge Cases

Matrix Strategies

Matrix strategies create multiple job instances from a single definition:

test:
  strategy:
    matrix:
      os: [ubuntu-latest, macos-latest]
      node: [14, 16, 18]
  runs-on: ${{ matrix.os }}

This creates 6 jobs: test (ubuntu-latest, 14), test (ubuntu-latest, 16), etc.

The visualizer represents this with a special node that shows “Matrix: 6 jobs” rather than cluttering the graph with all instances.

Reusable Workflows

GitHub Actions supports calling workflows from other repositories. The visualizer shows these as distinct nodes with a “reusable workflow” indicator, since you can’t visualize their internal structure without fetching the remote file.

Accessibility

Making a visual tool accessible to screen readers was a challenge. I added:

  • Textual view mode: A table-based representation of all job dependencies
  • Keyboard navigation: Full keyboard support for all interactions
  • ARIA labels: Proper semantic markup for assistive technologies
  • Focus management: Logical tab order and focus indicators

What I Learned

1. Graph Layouts Are Hard

Dagre does most of the work, but tuning the layout parameters to produce readable graphs took iteration:

  • Node spacing that works for both small and large workflows
  • Edge routing that minimizes overlaps
  • Rank separation that maintains hierarchy clarity

I ended up exposing layout direction as a user control since different workflows are more readable in different orientations.

2. YAML Validation Needs Context

Simple YAML parsers don’t know about GitHub Actions structure. Building a semantic validator required:

  • A schema of what fields are required/optional
  • Understanding of GitHub’s expression syntax (${{ }})
  • Knowledge of which trigger events are valid
  • Rules for dependency relationships

The validator provides warnings for non-critical issues (missing descriptions, unused outputs) while blocking on actual errors (invalid syntax, circular deps).

3. Browser Storage Is Underutilized

All workflow edits are automatically saved to localStorage. When you reload the page, your work is still there. This simple feature makes the tool much more practical for iterative workflow development.

No account required. No server. No database. Just browser storage.

Real-World Usage

I’ve used this tool to:

  • Debug deployment pipelines with 15+ jobs and complex dependencies
  • Visualize parallel test strategies across multiple OS/version matrices
  • Onboard new team members by showing them workflow structure visually
  • Refactor workflows by seeing which jobs could be parallelized

The most valuable use case: catching circular dependencies before pushing to GitHub. The GitHub UI just fails the workflow with a cryptic error. The visualizer shows you exactly where the cycle is.

Open Source

The project is MIT licensed and available on GitHub: dcotelo/actions

If you work with GitHub Actions regularly, try it out. If you have ideas for improvements, PRs are welcome.

Future Ideas

Things I might add:

  • Import from URL: Load workflows directly from GitHub repositories
  • Timeline view: Estimate execution time based on historical run data
  • Diff mode: Compare two workflow versions side-by-side
  • Export as image: Generate PNG/SVG of the graph for documentation

But for now, it solves the problem I had: understanding complex workflows without reading hundreds of lines of YAML.


The live demo is at dcotelo.github.io/actions. Give it a try with one of your own workflow files.