Understand your project's architecture before it becomes technical debt.
mdv is a language-agnostic CLI that parses go.mod, package.json, requirements.txt, and more into a unified, interactive dependency graph. It ships with a security auditor, a D3.js web UI, a diff engine, and a GitHub Actions composite action - covering the full dependency lifecycle in a single binary.
- Features
- Installation
- Quick Start
- Commands
- Output Formats
- GitHub Actions
- Build from Source
- Project Structure
- Branch Strategy
- CI/CD Pipelines
- Contributing
- License
| Feature | Description |
|---|---|
| Language support | Go (go.mod), Node (npm, Yarn v1/Berry, pnpm, Bun), Python (pip, Poetry, Pipenv, uv, pyproject.toml) |
| Security audit | Queries the OSV database for known CVEs per dependency version |
| License audit | Detects non-permissive and conflicting licenses across the dependency tree |
| Conflict detection | Flags the same package required at multiple incompatible versions |
| Interactive UI | Embedded D3.js graph with zoom, pan, depth filters, and a live audit panel |
| Multiple export formats | JSON (schema v1.1), Graphviz DOT, Mermaid |
| Dependency diff | Compares snapshots across any two git refs |
| Doc generation | Writes a DEPENDENCIES.md report, suitable for committing alongside releases |
| GitHub Actions | Drop-in composite action - analyse, audit, diff, and generate docs on every PR |
Requires Go 1.22+.
go install github.com/devekkx/module-dependency-visualizer/cmd/mdv@latestDownload the archive for your platform from the Releases page, then extract and move to $PATH:
# Linux (amd64)
curl -fsSL https://github.com/devekkx/module-dependency-visualizer/releases/latest/download/mdv_latest_linux_amd64.tar.gz \
| tar -xz -C /usr/local/bin mdv
# macOS (arm64 / Apple Silicon)
curl -fsSL https://github.com/devekkx/module-dependency-visualizer/releases/latest/download/mdv_latest_darwin_arm64.tar.gz \
| tar -xz -C /usr/local/bin mdvVerify checksums with the checksums.txt file included in each release.
No installation required - mount your project directory and run:
# Analyse
docker run --rm -v $(pwd):/work ghcr.io/devekkx/mdv analyse /work
# Export as DOT
docker run --rm -v $(pwd):/work ghcr.io/devekkx/mdv export /work --format dot
# Audit
docker run --rm -v $(pwd):/work ghcr.io/devekkx/mdv audit /work
# Serve (use --no-browser since there is no browser in the container)
docker run --rm -v $(pwd):/work -p 7777:7777 ghcr.io/devekkx/mdv serve /work --port 7777 --no-browserImages are published to ghcr.io/devekkx/mdv for linux/amd64 and linux/arm64.
# Summarise dependencies in your terminal
mdv analyse .
# Launch the interactive web UI (port is auto-assigned, shown in output)
mdv serve .
# Use a fixed port
mdv serve . --port 7777
# Export a Graphviz SVG
mdv export . --format dot | dot -Tsvg -o deps.svg
# Paste a Mermaid diagram into GitHub or Notion
mdv export . --format mermaid
# Run a full security & license audit
mdv audit .
# See what changed since main
mdv diff . --from main
# Generate DEPENDENCIES.md with audit data
mdv docs . --output DEPENDENCIES.md --auditParse a project and emit a dependency summary.
mdv analyse <path> [flags]
| Flag | Default | Description |
|---|---|---|
-o, --output |
- (stdout) |
Write output to file |
-d, --depth |
-1 (unlimited) |
Maximum dependency depth |
--include |
- | Keep modules matching regex (repeatable) |
--exclude |
- | Remove modules matching regex (repeatable) |
--no-indirect |
false |
Omit transitive dependencies |
--audit |
false |
Embed vulnerability/license/conflict data |
Export the graph to a renderable format.
mdv export <path> --format <fmt> [flags]
--format is required: dot, mermaid, or json. Accepts the same depth/filter flags as analyse.
Run a standalone security, license, and version-conflict audit.
mdv audit <path>
Checks each dependency against the OSV database, flags non-permissive licenses, and detects packages required at multiple incompatible versions.
Launch an interactive D3.js dependency graph in your browser.
mdv serve <path> [--port <n>] [--no-browser]
Show dependency changes between two git refs.
mdv diff <path> --from <ref> [--to <ref>]
--from defaults to HEAD~1. --to defaults to the working tree. Outputs added, removed, and version-bumped dependencies.
Generate a DEPENDENCIES.md documentation file.
mdv docs <path> [-o DEPENDENCIES.md] [--audit]
Print version, commit hash, and build date.
| Flag | Default | Description |
|---|---|---|
--log-level |
warn |
debug, info, warn, error |
--timeout |
30s |
Timeout for external tool calls |
The canonical, machine-readable graph. Powers all other exporters.
{
"schema_version": "1.1.0",
"generated_at": "2024-11-01T10:00:00Z",
"project": { "name": "github.com/example/app", "language": "go", ... },
"nodes": [{ "id": "github.com/spf13/cobra@v1.8.0", "kind": "module", "indirect": false, ... }],
"edges": [{ "from": "github.com/example/app@", "to": "github.com/spf13/cobra@v1.8.0", "kind": "depends_on" }],
"stats": { "node_count": 8, "edge_count": 12, "max_depth": 3, "has_cycles": false }
}See docs/schema-v1.md for the complete field reference.
mdv export . --format dot | dot -Tsvg -o deps.svg
mdv export . --format dot | dot -Tpng -o deps.pngBest for large graphs (hundreds to thousands of nodes).
mdv export . --format mermaidPaste directly into GitHub Markdown, Notion, or Confluence. Renders reliably up to ~500 nodes; use DOT for larger graphs.
A composite action is available at .github/actions/mdv.
- uses: devekkx/module-dependency-visualizer/.github/actions/mdv@main
with:
audit: "true"
diff: ${{ github.event.pull_request.base.sha }}
generate-docs: "true"Inputs
| Input | Default | Description |
|---|---|---|
path |
. |
Path to the project root |
audit |
false |
Run vulnerability and license audit |
diff |
"" |
Show dependency changes since this ref |
generate-docs |
false |
Write DEPENDENCIES.md |
version |
latest |
mdv release tag to pin (e.g. v0.3.0) |
Outputs
| Output | Description |
|---|---|
summary-file |
Path to DEPENDENCIES.md (when generate-docs: true) |
Requirements: Go 1.21+
git clone https://github.com/devekkx/module-dependency-visualizer.git
cd module-dependency-visualizer| Target | Description |
|---|---|
make build |
Compile binary → dist/mdv |
make test |
Run test suite |
make test-race |
Run with race detector |
make cover |
Tests + HTML coverage report |
make lint |
golangci-lint |
make vet |
go vet |
make gosec |
gosec security scanner |
make tidy |
go mod tidy + verify |
make clean |
Remove dist/ and coverage.out |
module-dependency-visualizer/
├── cmd/mdv/ # Entry point
├── internal/
│ ├── audit/ # OSV, license, and conflict checks
│ ├── cli/ # Cobra command definitions
│ ├── config/ # Build metadata (version, commit, date)
│ ├── diff/ # Dependency diff engine
│ ├── docgen/ # DEPENDENCIES.md generator
│ ├── exporter/
│ │ ├── dot/ # Graphviz DOT exporter
│ │ ├── jsonexp/ # JSON exporter
│ │ └── mermaid/ # Mermaid exporter
│ ├── graph/ # Immutable graph model, builder, filters, traversal
│ ├── logging/ # Structured logger
│ ├── provider/
│ │ ├── golang/ # go mod graph provider
│ │ ├── node/ # npm/yarn/pnpm/bun provider
│ │ └── python/ # pip/poetry/pyproject provider
│ ├── schema/ # JSON schema encode/decode (v1.1)
│ └── server/ # Embedded D3.js HTTP server
├── docs/
│ ├── adr/ # Architecture Decision Records
│ └── schema-v1.md # JSON schema reference
├── website/ # VitePress documentation site (→ Vercel)
│ └── docs/
│ ├── .vitepress/config.ts
│ ├── index.md
│ ├── getting-started.md
│ ├── commands.md
│ ├── formats.md
│ ├── schema.md
│ ├── github-actions.md
│ └── contributing.md
├── .github/
│ ├── actions/mdv/ # Composite GitHub Action
│ └── workflows/ # CI/CD pipelines (see below)
├── Makefile
├── go.mod
└── vercel.json # Docs site deployment config
The project follows a three-tier promotion model:
feature/* ──PR──▶ testing (integration branch - CI runs here)
testing ──PR──▶ develop (stable dev - dep checks run here)
develop ──PR──▶ production (release-ready - full gate runs here)
production ──tag──▶ v*.*.* (triggers GitHub Release)
| Branch | Purpose | Who merges here |
|---|---|---|
feature/* |
Individual feature or bug-fix branches | Developers |
testing |
Integration point; all code must pass CI before advancing | Developers via PR |
develop |
Stable development branch; dependency-clean and security-scanned | testing via PR |
production |
Always release-ready; gates are strictest | develop via PR |
Day-to-day flow:
- Branch off
testing:git checkout -b feature/my-thing testing - Open a PR to
testing- CI runs unit tests, lint, and build. - Once merged, open a PR from
testing→develop- dependency audit and security scan run. - When ready to ship, open a PR from
develop→production- the full gate runs (tests, lint, security, cross-platform build, docs). - Tag the merge commit on
production:git tag v1.2.3 && git push --tags- the release pipeline publishes binaries to GitHub Releases.
All pipelines live in .github/workflows/.
Runs on every pull request targeting testing. Stale runs are cancelled automatically on force-push.
| Job | What it does |
|---|---|
| Test (matrix: Go 1.22, 1.23, stable) | go mod tidy drift check, go vet, tests with race detector, 80% coverage gate |
| Lint | golangci-lint with the project's .golangci.yml ruleset |
| Build | make build - verifies the binary compiles; uploads artifact for 3 days |
The coverage report artifact (coverage.out) is uploaded from the stable matrix leg and kept for 7 days.
Runs on every pull request targeting develop. Posts a single auto-updating comment on the PR.
| Job | What it does |
|---|---|
| Dependency Audit | mdv analyse --audit, dependency diff against the base SHA, govulncheck (informational), generates DEPENDENCIES.md, posts/updates PR comment |
| Security Scan | gosec in SARIF mode - results uploaded to GitHub Security tab |
The strictest gate. All jobs must pass before merging to production.
| Job | What it does |
|---|---|
| Full Test Suite | Same as CI but runs once, not matrix |
| Lint | golangci-lint |
| Security Gate | govulncheck (blocking - non-zero exit fails the PR), gosec SARIF |
| Cross-platform Build (5-way matrix) | linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64 - all with CGO_ENABLED=0 |
| Docs Build | npm ci && npm run build in website/ - verifies the docs site compiles |
Triggered by pushing a semver tag to production. Builds static binaries for all platforms, packages them with README.md and LICENSE, generates checksums.txt, and publishes a GitHub Release with auto-generated release notes.
# Cut a release from production
git checkout production
git tag v1.2.3
git push origin v1.2.3Artifacts produced per release:
mdv_v1.2.3_linux_amd64.tar.gz
mdv_v1.2.3_linux_arm64.tar.gz
mdv_v1.2.3_darwin_amd64.tar.gz
mdv_v1.2.3_darwin_arm64.tar.gz
mdv_v1.2.3_windows_amd64.zip
checksums.txt
Validates the VitePress build on any PR that modifies the website/ directory. Uploads the built site as an artifact for preview.
See CONTRIBUTING.md for the full guide.
Quick summary:
- Branch off
testing - Make focused changes and write tests (80% coverage required)
- Open a PR to
testing- CI must pass - Follow Conventional Commits:
feat:,fix:,docs:,refactor:,test:,chore: