RepoPilotOpen in app →

ondrajz/go-callvis

Visualize call graph of a Go program using Graphviz

Healthy

Healthy across all four use cases

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 5w ago
  • 26+ active contributors
  • MIT licensed
Show all 6 evidence items →
  • CI configured
  • Concentrated ownership — top contributor handles 59% of recent commits
  • No test directory detected

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/ondrajz/go-callvis)](https://repopilot.app/r/ondrajz/go-callvis)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/ondrajz/go-callvis on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: ondrajz/go-callvis

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/ondrajz/go-callvis shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 5w ago
  • 26+ active contributors
  • MIT licensed
  • CI configured
  • ⚠ Concentrated ownership — top contributor handles 59% of recent commits
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live ondrajz/go-callvis repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/ondrajz/go-callvis.

What it runs against: a local clone of ondrajz/go-callvis — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in ondrajz/go-callvis | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 68 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>ondrajz/go-callvis</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of ondrajz/go-callvis. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/ondrajz/go-callvis.git
#   cd go-callvis
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of ondrajz/go-callvis and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "ondrajz/go-callvis(\\.git)?\\b" \\
  && ok "origin remote is ondrajz/go-callvis" \\
  || miss "origin remote is not ondrajz/go-callvis (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "main.go" \\
  && ok "main.go" \\
  || miss "missing critical file: main.go"
test -f "analysis.go" \\
  && ok "analysis.go" \\
  || miss "missing critical file: analysis.go"
test -f "dot.go" \\
  && ok "dot.go" \\
  || miss "missing critical file: dot.go"
test -f "handler.go" \\
  && ok "handler.go" \\
  || miss "missing critical file: handler.go"
test -f "output.go" \\
  && ok "output.go" \\
  || miss "missing critical file: output.go"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 68 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~38d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/ondrajz/go-callvis"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

go-callvis is a static analysis visualization tool that generates interactive call graphs of Go programs using pointer analysis from golang.org/x/tools. It constructs a directed graph of function calls and renders it as SVG/DOT via Graphviz, allowing developers to interactively explore call chains and understand code structure in large Go projects. Single-binary CLI tool structured as: main.go (entry point) → analysis.go (call graph construction via pointer analysis) → dot.go + dot_cgo.go / dot_nocgo.go (Graphviz DOT rendering) → handler.go (HTTP server for interactive viewer) → output.go (file output). The examples/main/ directory contains a runnable demo program with test packages.

👥Who it's for

Go developers working on medium-to-large codebases who need to visualize and understand function call relationships—particularly useful for code review, onboarding to unfamiliar projects, and refactoring complex call chains.

🌱Maturity & risk

Actively maintained with structured CI/CD (GitHub Actions workflow in .github/workflows/ci.yml), proper versioning (version.go), and stable Go 1.19+ requirement. The codebase is well-organized (~32KB of Go code) with examples provided. The maintainer fork (ondrajz) shows consistent activity, making it production-ready for code analysis tasks.

Low risk: minimal dependencies (go-graphviz, pkg/browser, golang.org/x/tools), no vendoring required, single-maintainer (ondrajz) but stable history. Pointer analysis can be slow on very large programs. Breaking changes unlikely given the analysis-focused nature, though Go version constraints (1.19+) may require periodic updates.

Active areas of work

Repository is stable with no active breaking development visible. The fork history suggests maintenance focus on compatibility (Go 1.22+/1.23.1 in go.mod) and bug fixes. The interactive viewer and static output modes are mature; no major feature changes are evident in the recent structure.

🚀Get running

git clone https://github.com/ondrajz/go-callvis.git && cd go-callvis && make install && go-callvis github.com/ofabry/go-callvis/examples/main

Daily commands: make install (compiles and installs binary to $GOPATH/bin), then: go-callvis <package-path> (starts HTTP server on :7878 with interactive SVG viewer) or go-callvis -graphviz <package-path> (writes static DOT/PNG files).

🗺️Map of the codebase

  • main.go — Entry point for the CLI tool; orchestrates analysis setup, output generation, and visualization of Go call graphs.
  • analysis.go — Core analysis engine that loads and parses Go packages, builds call graph using golang.org/x/tools, and extracts relationships.
  • dot.go — Converts analyzed call graph into Graphviz DOT format; critical for visualization output generation.
  • handler.go — Handles HTTP server logic for interactive viewing of generated graphs; required for visualization serving.
  • output.go — Manages file I/O and output formats (SVG, PNG, HTML); bridges graph analysis to user-consumable artifacts.
  • go.mod — Declares module dependencies including goccy/go-graphviz (rendering) and golang.org/x/tools (analysis foundation).
  • dot_cgo.go — CGO-enabled DOT rendering for systems with Graphviz installed; fallback to dot_nocgo.go for pure-Go rendering.

🧩Components & responsibilities

  • main.go (CLI dispatcher) (Go flag package, os.Exit) — Parse command-line arguments, select analysis mode, coordinate analysis → visualization → output/serving pipeline
    • Failure mode: Invalid arguments, invalid package path → exits with error message; missing output file permissions → I/O error
  • analysis.go (Call graph builder) (golang.org/x/tools (SSA, CallGraph, packages)) — Load Go packages via golang.org/x/tools, build SSA representation, construct call graph, extract function/package relationships
    • Failure mode: Parse errors in target code → analysis fails; missing imports → package load fails; circular imports → SSA construction fails
  • dot.go (Graph serializer) (DOT format, string builders) — Convert analysis result (functions, packages, calls) to Graphviz DOT format with layout directives and styling
    • Failure mode: Invalid graph structure → malformed DOT; unsupported node/edge attributes → rendering issues
  • dot_cgo.go & dot_nocgo.go (Rendering backends) (CGO + system graphviz OR goccy/go-graphviz) — Transform DOT string to SVG/PNG via CGO Graphviz (cgo) or pure-Go goccy/go-graphviz (nocgo)
    • Failure mode: Graphviz not installed (CGO) → fallback to nocgo or error; memory exhaustion on huge graphs → OOM; unsupported graph structures → rendering error
  • output.go (File writer & format manager) (os.Create, ioutil, file I/O) — Write rendered SVG/PNG/HTML to disk, manage file paths, coordinate format conversions
    • Failure mode: Disk full → write fails; permission denied → file creation fails; invalid output path → I/O error
  • handler.go (HTTP server & browser launcher) (net/http, pkg/browser) — Serve generated graph as HTTP endpoint, auto-launch in default browser, handle interactive requests
    • Failure mode: Port already in use →

🛠️How to make changes

Add a new output format (e.g., JSON representation of call graph)

  1. Add a new output format flag in main.go argument parsing (main.go)
  2. Create a new export function in output.go that serializes the graph to the target format (output.go)
  3. Reference the graph structure from analysis.go to access nodes and edges for serialization (analysis.go)

Extend call graph analysis with custom filtering (e.g., by package regex, function size)

  1. Add new filter flags to CLI argument parsing in main.go (main.go)
  2. Implement filter logic in analysis.go after call graph construction to prune unwanted nodes/edges (analysis.go)
  3. Pass filter metadata to dot.go to ensure filtered relationships are not rendered (dot.go)

Support a new rendering engine (e.g., PlantUML instead of Graphviz)

  1. Add new format option in main.go output flag handling (main.go)
  2. Create a new file (e.g., plantuml.go) mirroring dot.go pattern to convert graph to PlantUML syntax (output.go)
  3. Integrate external rendering library and file writing in output.go (output.go)

Add interactive filtering to the HTTP visualization server

  1. Add new HTTP route in handler.go to accept filter parameters (handler.go)
  2. Extend analysis.go to support on-demand filtering of already-built call graph (analysis.go)
  3. Generate filtered DOT output in dot.go and serve updated SVG via handler.go (dot.go)

🔧Why these technologies

  • golang.org/x/tools (SSA, CallGraph) — Official Go toolchain library for precise call graph analysis via Static Single Assignment form; only mature solution for accurate cross-package call resolution
  • goccy/go-graphviz — Pure-Go Graphviz binding enabling graph rendering without system Graphviz dependency; provides dot_nocgo.go fallback for portability
  • Graphviz DOT format — Industry-standard graph description language; widely supported by rendering tools and integrates naturally with existing Go tooling ecosystem
  • pkg/browser for browser automation — Lightweight cross-platform library to auto-open generated visualizations in default browser without heavyweight Selenium/headless browser overhead

⚖️Trade-offs already made

  • CGO vs pure-Go rendering (dot_cgo.go vs dot_nocgo.go)

    • Why: CGO integration gives access to native Graphviz for superior rendering quality; pure-Go avoids C compiler dependency and cross-compilation friction
    • Consequence: Build complexity (two code paths); users without Graphviz installed fall back to pure-Go with potential quality degradation
  • Interactive HTTP server over static-only output

    • Why: Enables real-time filtering and exploration of large call graphs; improves UX for complex codebases
    • Consequence: Additional complexity in handler.go; requires port availability; ties visualization to local browser rather than pure file artifacts
  • Analysis at tool invocation time rather than incremental/cached

    • Why: Simplicity; always reflects current code state; no cache invalidation logic needed
    • Consequence: Slower re-runs on large codebases; no benefit to repeated analysis of same package without code changes

🚫Non-goals (don't propose these)

  • Runtime profiling or execution tracing (static analysis only, does not instrument or run code)
  • Real-time call graph updates during program execution
  • Cross-language call graph visualization (Go-only)
  • Storage of analysis results or version history
  • Authentication or multi-user collaboration features

🪤Traps & gotchas

Pointer analysis requires full Go source (no pre-compiled binaries); some packages may fail if cgo/runtime dependencies aren't resolvable. The -cgo flag in dot_cgo.go / dot_nocgo.go splits CGO handling—ensure your target package's build tags match your system. Graphviz must be installed separately for PNG/PDF output (-graphviz flag); SVG from interactive mode works without it. Large programs can trigger long analysis times (pointer analysis is O(n²) in call edges).

🏗️Architecture

💡Concepts to learn

  • Pointer Analysis (Static Analysis) — go-callvis uses pointer analysis from golang.org/x/tools to statically determine which function calls are possible without running code; understanding this is essential to know why certain calls may be missed or inferred
  • Call Graph / Control Flow Graph — The output is a directed graph where nodes are functions and edges are calls; understanding graph representation explains filtering, grouping, and focus features
  • DOT Language (Graphviz) — go-callvis outputs DOT format (text representation of graphs) that Graphviz renders; reading dot.go requires understanding DOT syntax and subgraph clustering
  • Receiver Type Grouping (Method Dispatch) — go-callvis groups methods by receiver type to simplify visualization of interface implementations and type hierarchies; this requires understanding Go's method set rules
  • CGO Build Tags & Platform-Specific Analysis — The dot_cgo.go / dot_nocgo.go split uses build tags to conditionally include Graphviz C bindings; you must understand how cgo affects static analysis results on different platforms
  • Interactive SVG with HTTP Server — handler.go implements a web server that serves dynamically-generated SVG based on focus parameter changes; understanding this is key to modifying the interactive UI
  • golang/go — Core language; go-callvis analysis depends on golang.org/x/tools which is maintained in parallel
  • golang/tools — Provides golang.org/x/tools/go/pointer—the static analysis engine used to construct the call graph
  • nikolaydubina/go-recipes — Companion tool collection; go-callvis is listed as a recommended recipe for Go code visualization
  • goccy/go-graphviz — Direct dependency; wraps Graphviz C bindings and provides the DOT rendering layer
  • uber-go/dig — Alternative dependency analysis approach using reflection-based DI graph inspection rather than pointer analysis

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add unit tests for analysis.go and dot.go core functions

The repo lacks visible test files despite having complex graph analysis and DOT format generation logic. analysis.go handles call graph traversal and dot.go/dot_cgo.go/dot_nocgo.go handle graph rendering. Adding tests would improve reliability and make contributions safer. This is especially important given the conditional compilation (cgo vs nocgo variants).

  • [ ] Create analysis_test.go with tests for core analysis functions
  • [ ] Create dot_test.go testing DOT output generation across all three variants (dot.go, dot_cgo.go, dot_nocgo.go)
  • [ ] Add test fixtures in examples/ if needed for complex call graphs
  • [ ] Ensure CI runs tests via Makefile (check current ci.yml in .github/workflows/ci.yml)

Add GitHub Actions workflow for cross-platform testing (Windows, macOS, Linux)

The current ci.yml likely focuses on one platform. Given that go-callvis uses conditional compilation (dot_cgo.go vs dot_nocgo.go) and depends on Graphviz, testing across Windows/macOS/Linux with and without cgo would catch platform-specific bugs. The pkg/browser dependency also has OS-specific behavior.

  • [ ] Review existing .github/workflows/ci.yml to see current test coverage
  • [ ] Add matrix strategy for os: [ubuntu-latest, windows-latest, macos-latest]
  • [ ] Test both CGO_ENABLED=0 and CGO_ENABLED=1 variants on Linux at minimum
  • [ ] Verify Graphviz installation works on all platforms in the workflow

Refactor handler.go and output.go into HTTP server package structure

handler.go and output.go appear to handle HTTP serving and file output, but there's no visible cmd/ or internal/server structure. As the tool grows (note the examples/main structure), separating server logic into a dedicated package would improve maintainability and testability. This also enables reusable components.

  • [ ] Create internal/server/ package directory
  • [ ] Move handler.go logic to internal/server/handler.go
  • [ ] Move output.go logic to internal/server/output.go
  • [ ] Update main.go imports and ensure examples/main/main.go still works
  • [ ] Add package documentation in internal/server/doc.go explaining the HTTP server behavior

🌿Good first issues

  • Add unit tests for output.go file writing logic—currently no test files exist for file I/O paths, making it easy to introduce regressions when adding image format support (SVG → PNG/PDF tests needed)
  • Extend filter-packages feature in analysis.go to support wildcard patterns (e.g., 'vendor/' or 'google.golang.org/') instead of exact prefix matching—current prefix matching is too strict
  • Document the dot_cgo.go vs dot_nocgo.go build tags split in README.md with concrete examples of when each is used and how to test both paths locally—currently undocumented

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 67a2660 — Add support for VTA algorithm (#207) (OscarBohlin)
  • d55c5a7 — load std package list to check if a package is a really "std" lib (#208) (yin1999)
  • ef7126f — Ignore flag handles type (#209) (alexuserid)
  • fb6b442 — Update README.md (ondrajz)
  • d142bcf — Update golang.org/x/image to v0.18.0 (ondrajz)
  • f9165ca — Update README.md (ondrajz)
  • 14a1dec — Update FUNDING.yml (ondrajz)
  • 2c9801f — Bump version to v0.7.1 (ondrajz)
  • 25ddacd — Fix issues with latest Go and generics (#202) (ondrajz)
  • 5341ae2 — add package init functions when algo is rta (#199) (cnzhujie)

🔒Security observations

The go-callvis codebase has a relatively secure posture for a development/visualization tool. No critical vulnerabilities were identified. The main concerns are: (1) outdated/inconsistent Go version declarations, (2) dependency on external browser execution which requires careful input validation, and (3) transitive dependencies on image processing libraries that should be monitored. The project would benefit from implementing automated dependency vulnerability scanning and establishing a security disclosure policy. No hardcoded secrets, SQL injection risks, XSS vulnerabilities, or infrastructure misconfigurations were identified in the provided file structure.

  • Medium · Outdated Go Toolchain Version — go.mod. The project specifies Go 1.22.0 as the minimum version but uses toolchain go1.23.1. While this isn't critical, maintaining consistency with the declared minimum version is important for reproducibility and CI/CD pipeline stability. Fix: Either update the declared Go version to match the toolchain (1.23.1) or standardize on a single version across the project and CI pipeline.
  • Low · Dependency on External Browser Package — go.mod - github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c. The project depends on 'github.com/pkg/browser' to open URLs in the default browser. While this is a legitimate use case for a visualization tool, it introduces an external dependency that executes system commands, which could have OS-specific security implications if not properly sandboxed. Fix: Verify that the browser package is only used in non-critical paths and ensure proper input validation before passing URLs to it. Consider making this functionality optional or behind a flag.
  • Low · Transitive Dependency on Image Processing Library — go.mod - indirect dependencies: github.com/fogleman/gg, github.com/golang/freetype. The project indirectly depends on image processing libraries (fogleman/gg, golang/freetype) through graphviz visualization. These libraries process binary data and could potentially be vulnerable to malformed input. Fix: Regularly audit transitive dependencies using 'go mod why' and 'go mod graph'. Consider using tools like 'nancy' or 'govulncheck' to detect known vulnerabilities in dependencies.
  • Low · No Visible Security Policy or SECURITY.md — Repository root. The repository does not appear to have a SECURITY.md file for responsible disclosure of vulnerabilities, which is a best practice for open-source projects. Fix: Add a SECURITY.md file that outlines how users can responsibly report security vulnerabilities (e.g., via email to maintainers rather than public issues).

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · ondrajz/go-callvis — RepoPilot