Wanda π
A fast, interactive terminal graph visualizer written in Go. Wanda is a port of the Cosmo TypeScript library, bringing beautiful graph visualization to the terminal with the power of the Bubbletea ecosystem.

β¨ Features
- Library & CLI: Use as a standalone tool or embed in your own applications
- Interactive Visualization: Explore graphs and trees with smooth pan and zoom
- Multiple Formats: Load graphs from JSON or YAML files
- Beautiful Themes: Choose from 4 built-in color schemes (Aura, Dracula, Atom, Catppuccin)
- Configurable Keybindings: Customize navigation keys to your preference
- Stylable with Lipgloss: Full control over visual appearance using lipgloss styles
- Vim-Style Navigation: Navigate with hjkl or arrow keys (customizable)
- Search: Quickly find nodes by ID or value
- Keyboard Driven: Fully accessible via keyboard shortcuts
- Bubbletea Component: Integrate seamlessly into existing bubbletea applications
- Fast & Lightweight: Built with Go for speed and minimal resource usage
π Installation
From Source
go install github.com/clstb/wanda/cmd/wanda@latest
Wanda packages a compiled version of elkjs for layout algorithms, thus install can be slow.
Build Locally
git clone https://github.com/clstb/wanda.git
cd wanda
make build
π Usage
Wanda can be used both as a standalone CLI tool and as a library in your own Go applications.
CLI Usage
Visualize a Graph
wanda visualize --file graph.json
wanda visualize --file graph.yaml --theme dracula
wanda visualize --file graph.json --direction right
wanda visualize --file graph.json --theme atom --direction left
Available flags:
--file, -f (required): Path to graph file (JSON or YAML)
--theme, -t: Color theme (aura, dracula, atom, catppuccin) - default: aura
--direction, -d: Layout direction (down, up, left, right) - default: down
Library Usage
Use wanda as a reusable bubbletea component in your own applications.
Simple Example (Loading from File)
import (
"github.com/clstb/wanda/pkg/graph"
"github.com/clstb/wanda/pkg/layout"
"github.com/clstb/wanda/pkg/parser"
"github.com/clstb/wanda/pkg/tui"
)
// Load and visualize
g, _ := parser.LoadFromFile("graph.json")
layout.Layout(g)
tui.Run(g) // Simple!
Programmatic Graph Creation
Create graphs directly in code without needing files:
import (
"github.com/clstb/wanda/pkg/graph"
"github.com/clstb/wanda/pkg/layout"
"github.com/clstb/wanda/pkg/tui"
)
// Create nodes
nodes := []graph.Node{
{ID: "1", Value: "Root"},
{ID: "2", Value: "Child A"},
{ID: "3", Value: "Child B"},
{ID: "4", Value: "Grandchild A1"},
{ID: "5", Value: "Grandchild A2"},
{ID: "6", Value: "Grandchild B1"},
}
// Create edges to form a tree
edges := []graph.Edge{
{ID: "e1", Source: "1", Target: "2"},
{ID: "e2", Source: "1", Target: "3"},
{ID: "e3", Source: "2", Target: "4"},
{ID: "e4", Source: "2", Target: "5"},
{ID: "e5", Source: "3", Target: "6"},
}
// Create, layout, and visualize
g := graph.NewGraph(nodes, edges)
layout.Layout(g)
tui.Run(g)
Custom Keybindings
import "github.com/charmbracelet/bubbles/key"
customKeys := tui.DefaultKeyMap()
customKeys.Up = key.NewBinding(key.WithKeys("w", "up"))
customKeys.Down = key.NewBinding(key.WithKeys("s", "down"))
customKeys.Left = key.NewBinding(key.WithKeys("a", "left"))
customKeys.Right = key.NewBinding(key.WithKeys("d", "right"))
tui.Run(g, tui.WithKeyMap(customKeys))
Custom Styles with Lipgloss
import (
"github.com/charmbracelet/lipgloss"
"github.com/clstb/wanda/pkg/tui/theme"
)
customStyles := &theme.Styles{
Node: lipgloss.NewStyle().
Foreground(lipgloss.Color("#00FFFF")).
BorderStyle(lipgloss.DoubleBorder()),
NodeFocused: lipgloss.NewStyle().
Foreground(lipgloss.Color("#FF00FF")).
Bold(true),
// ... customize all styles
}
tui.Run(g, tui.WithStyles(customStyles))
Integration with Existing Bubbletea Apps
// Create the model
m, _ := tui.NewModel(
tui.WithGraph(g),
tui.WithTheme("dracula"),
tui.WithKeyMap(customKeys),
)
// Use in your bubbletea program
p := tea.NewProgram(m, tea.WithAltScreen())
p.Run()
Custom Layout Direction
Configure the graph layout direction (default is top-to-bottom):
import "github.com/clstb/wanda/pkg/layout"
// Left-to-right layout
tui.Run(g, tui.WithLayoutDirection(layout.DirectionRight))
// Other options: DirectionDown, DirectionUp, DirectionLeft, DirectionRight
// Or set multiple layout options:
opts := layout.LayoutOptions{
Direction: layout.DirectionRight,
NodeSpacing: 10,
}
tui.Run(g, tui.WithLayoutOptions(opts))
Available Options
Customize wanda's behavior with these functional options:
WithGraph(*graph.Graph) - Set the graph to visualize
WithTheme(string) - Use a built-in theme (aura, dracula, atom, catppuccin)
WithStyles(*theme.Styles) - Use completely custom lipgloss styles
WithKeyMap(KeyMap) - Customize keybindings
WithAutoTheme() - Auto-detect light/dark theme
WithSelectedNode(string) - Set initially selected node
WithAutoSelectFirst() - Automatically select first node
WithInitialZoom(float64) - Set initial zoom level (0.5-2.0)
WithInitialPan(x, y int) - Set initial viewport offset
WithLayoutDirection(layout.Direction) - Set graph direction (DirectionDown, DirectionUp, DirectionRight, DirectionLeft)
WithLayoutOptions(layout.LayoutOptions) - Set custom layout options (direction, spacing)
See examples/library_usage for complete working examples.
Keyboard Controls
Navigation
ββββ or hjkl - Move to node in direction
Shift+ββββ or Shift+HJKL - Scroll view
c - Center and fit view
Tab - Select next node
Shift+Tab - Select previous node
Actions
/ - Search for nodes
Space or ESC - Open menu
? - Show keybindings help
q or Ctrl+C - Quit
Wanda accepts JSON or YAML files with the following structure:
JSON Example
{
"nodes": [
{ "id": "1", "value": "Start" },
{ "id": "2", "value": "Process" },
{ "id": "3", "value": "End" }
],
"edges": [
{ "id": "e1", "source": "1", "target": "2" },
{ "id": "e2", "source": "2", "target": "3" }
]
}
YAML Example
nodes:
- id: "1"
value: "Start"
- id: "2"
value: "Process"
- id: "3"
value: "End"
edges:
- id: "e1"
source: "1"
target: "2"
- id: "e2"
source: "2"
target: "3"
π¨ Themes
Wanda includes 4 beautiful color schemes:
- Aura (default) - Dark theme with vibrant accents
- Dracula - Popular dark theme with purple highlights
- Atom - One Dark inspired theme
- Catppuccin - Soothing pastel theme
Change themes with the --theme flag or from the menu (Space β Change Theme).
ποΈ Architecture
Wanda is built with modern Go libraries:
- Bubbletea - TUI framework with The Elm Architecture
- Lipgloss - Style definitions and layout
- Bubbles - Reusable TUI components
- Cobra - CLI framework
Project Structure
wanda/
βββ cmd/wanda/ # CLI entry point (standalone usage)
βββ pkg/ # Library packages (reusable)
β βββ graph/ # Graph data structures
β βββ parser/ # JSON/YAML parsing
β βββ layout/ # Graph layout algorithms
β βββ export/ # Export to JSON/YAML
β βββ tui/ # Terminal UI (bubbletea component)
β βββ theme/ # Color schemes and lipgloss styles
β βββ keymap.go # Configurable keybindings
β βββ model.go # Bubbletea model
β βββ options.go # Functional options
β βββ messages.go # Event messages
β βββ render.go # Rendering logic
βββ examples/
β βββ library_usage/ # Library usage examples
β βββ *.{json,yaml} # Example graph files
βββ openspec/ # OpenSpec proposal docs
π§ͺ Development
Prerequisites
- Go 1.25.5 or higher
- Make (for running development commands)
- No Node.js required! (elkjs layout engine is embedded)
First Time Setup
Install all development tools automatically:
make setup-tools
This installs:
- goimports - Code formatting with import management
- staticcheck - Fast, accurate static analysis
- golangci-lint - Comprehensive meta-linter
- govulncheck - Vulnerability scanner
Development Workflow
# Format code (uses goimports)
make fmt
# Run tests with race detector
make test
# Run staticcheck
make staticcheck
# Run all linters (includes staticcheck)
make lint
# Check for vulnerabilities
make vuln
# Run ALL checks (format + vet + lint + vuln + test)
make check
# Build binary
make build
# Run with example
make run-example
Available Make Targets
make help # Show all targets
make setup-tools # Install dev tools (one-time)
make build # Build binary
make test # Run tests with race detector
make test-coverage # Tests + HTML coverage report
make fmt # Format code with goimports
make fmt-check # Check formatting (CI)
make vet # Run go vet
make staticcheck # Run staticcheck
make lint # Run golangci-lint
make vuln # Check vulnerabilities
make check # Run ALL checks (CI-ready)
make clean # Clean artifacts
make run-example # Run with example file
- staticcheck (https://staticcheck.dev) - Primary static analyzer
- golangci-lint - Runs multiple linters including staticcheck
- goimports - Import management and code formatting
- govulncheck - Security vulnerability detection
Test Coverage
Current coverage:
- export: 86.5%
- graph: 95.1%
- layout: 76.8% (91% function-level average)
- parser: 88.9%
- tui: 80.0%
- tui/theme: 91.7%
- Overall: 195+ tests passing
Generate coverage report:
make test-coverage # Opens HTML report in browser
Continuous Integration
The make check target is designed for CI pipelines and runs:
- Format checking (not auto-format)
- go vet
- staticcheck
- golangci-lint
- govulncheck
- All tests with race detector
Example CI config:
steps:
- name: Setup
run: make setup-tools
- name: Check
run: make check
π§ Technical Details
ELK Layout Engine
Wanda uses the Eclipse Layout Kernel (elkjs) for graph layout algorithms. The engine is completely self-contained:
- No Node.js required: Pre-compiled standalone binaries are embedded in the Go binary
- Zero runtime dependencies: Everything is bundled using @yao-pkg/pkg
- Cross-platform: Supports macOS (Intel/ARM), Linux (x64/ARM64), Windows (x64)
- Embedded at compile time: Platform-specific binary (~50-63MB) is automatically selected
The layout engine automatically detects your platform and uses the appropriate embedded binary. Users don't need to install Node.js, npm, or any other dependencies!
Project Stats
- Lines of Code: ~3,657
- Test Coverage: 195+ test cases passing (80%+ coverage on core packages)
- Packages: 6 main packages (graph, parser, export, layout, tui, theme)
- Dependencies: Bubbletea ecosystem + Cobra
- Binary Size: ~63MB (includes embedded elkjs layout engine)
πΊοΈ Roadmap
- Core graph visualization
- Interactive navigation (pan, zoom, search)
- Multiple themes
- JSON/YAML file support
- Export to JSON/YAML
- Comprehensive test coverage (>80% on core packages)
- Improved graph layout algorithms (force-directed, hierarchical)
- Terminal responsiveness and resize handling
- Configuration file support
- Auto-completion for shell commands
- CI/CD pipeline and binary releases
- SVG/PNG export
π€ Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development Guidelines
- Follow the existing code style (use
gofmt)
- Write tests for new features
- Update documentation as needed
- Ensure all tests pass before submitting PR
π License
MIT License - see LICENSE file for details
π Acknowledgments
Made with β€οΈ using Go and Bubbletea