A self-contained, interactive Go coverage dashboard. Feed it a cover.out file and get a browsable HTML report with per-file highlighting, folder drill-down, and optional HTTP route coverage.
# install
go install github.com/sixtineai/sixtine-coverage@latest
# generate coverage report in your go project
go test -coverprofile=cover.out ./...
# render to html
sixtine-coverage -coverage cover.out -codebase . -out coverage.html- Open the bundled demo report: Demo report
Two ways to use it:
| Mode | Best for | Output |
|---|---|---|
CLI (go install) |
CI pipelines, sharing reports | Single .html file you can open anywhere |
| Docker | Persistent dashboards, team servers | Live web UI on port 80 |
go install github.com/sixtineai/sixtine-coverageThis gives you the sixtine-coverage binary. The HTML template is compiled into the binary, no extra files needed.
# default
sixtine-coverage -coverage cover.out
# full, with route coverage
sixtine-coverage \
-coverage ./cover.out \
-codebase /path/to/your-project \
-route-coverage ./route-coverage.rcov \
-out report.htmlOpen report.html in any browser. Everything (code, data, UI) is inlined, no server required.
| Flag | Description | Default |
|---|---|---|
-coverage |
Path to Go cover.out file |
(required) |
-codebase |
Path to the Go source code root | ./ |
-route-coverage |
Path to route-coverage.rcov file |
(none) |
-out |
Output HTML file path | coverage.html |
# in your CI pipeline
go test -coverprofile=cover.out ./...
sixtine-coverage -coverage cover.out -codebase . -out coverage.html
# upload coverage.html as a build artifactMount your coverage data and source code into the container. The dashboard auto-loads on startup.
docker run -d -p 8080:80 \
-v $(pwd)/cover.out:/data/coverage/cover.out:ro \
-v $(pwd):/data/code:ro \
-e SIXTINEAI_COVERAGE_URL=/data/coverage/cover.out \
-e SIXTINEAI_SOURCE_ROOT=/data/code/ \
ghcr.io/sixtineai/sixtine-coverage:latestThen open http://localhost:8080.
Save this as docker-compose.yml next to your project:
services:
coverage:
image: ghcr.io/sixtineai/sixtine-coverage:latest
ports:
- "8080:80"
volumes:
- ./cover.out:/data/coverage/cover.out:ro
- ./:/data/code:ro
# Optional: mount route coverage
# - ./route-coverage.rcov:/data/coverage/route-coverage.rcov:ro
environment:
SIXTINEAI_COVERAGE_URL: /data/coverage/cover.out
SIXTINEAI_SOURCE_ROOT: /data/code/
# SIXTINEAI_ROUTE_COVERAGE_URL: /data/coverage/route-coverage.rcovgo test -coverprofile=cover.out ./...
docker compose up -d
# → http://localhost:8080| Variable | Description | Default |
|---|---|---|
SIXTINEAI_COVERAGE_URL |
URL/path to the cover.out file |
./cover.out |
SIXTINEAI_SOURCE_ROOT |
Base path for serving Go source files | (empty) |
SIXTINEAI_MODULE_PREFIX |
Module prefix to strip from paths (auto-detected from coverage) | (empty) |
SIXTINEAI_ROUTE_COVERAGE_URL |
URL/path to a route-coverage.json file |
(empty) |
When a coverage URL or inline data is set, the config screen is skipped and data loads automatically.
Standard Go coverage profile:
go test -coverprofile=cover.out ./...Optional. A text-based route coverage profile (inspired by Go's cover.out format). Lists all API routes with hit counts and status code breakdowns:
mode: status
# AuthenticationService
GET /api/rest/v1/authentication/modes 200:1
POST /api/rest/v1/authentication/login 5 200:2
POST /api/rest/v1/authentication/refresh-token 200:2 -1:1
# TenantService
GET /api/rest/v1/tenants 200:4
GET /api/rest/v1/tenants/{id} 0
Format rules:
mode: statusheader line# ServiceTagcomment lines group routes by service- Each route:
METHOD /path counts 0= uncovered (zero hits)4= 4 calls with unspecified status200:3= 3 calls returning HTTP 2002 200:3= 2 unspecified + 3×200 = 5 total hits-1:2= 2 connection failures
The project is a Vue 3 + Vite SPA with a Go CLI wrapper that produces self-contained HTML reports.
- Node.js ≥ 18 and pnpm
- Go ≥ 1.21
├── main.go # Go CLI, embeds dist/index.html, injects data
├── dist/index.html # Built single-file SPA (committed, used by go:embed)
├── index.html # Vite entry point (dev)
├── vite.config.js # Vite config, standard + single-file mode
├── src/
│ ├── main.js # Vue app bootstrap
│ ├── App.vue # Root component, config screen + main layout
│ ├── config/index.js # Runtime config from window.configs / env vars
│ ├── components/
│ │ ├── ConfigScreen.vue # Initial setup form (URL inputs)
│ │ ├── DashboardView.vue # Overview with coverage stats
│ │ ├── FilesView.vue # Flat file list with coverage bars
│ │ ├── FileCoverage.vue # Per-file source view with line highlighting
│ │ ├── FolderView.vue # Folder-level aggregation
│ │ ├── TreeExplorer.vue # Folder tree sidebar
│ │ ├── TreeNode.vue # Recursive tree node
│ │ └── RouteCoverageView.vue # HTTP route coverage table
│ └── utils/
│ ├── coverage.js # cover.out parser → file/line/statement data
│ ├── data.js # Data loading (fetch or gzip+base64 decode)
│ └── routeCoverage.js # Route coverage rcov parser
└── docker/
├── Dockerfile # Multi-stage: node build → nginx
├── nginx.conf # Serves SPA + mounted data volumes
└── entrypoint.sh # Injects SIXTINEAI_* env vars into HTML at boot
- Vite builds the Vue app into a single
dist/index.html(all JS/CSS inlined viavite-plugin-singlefile). - The HTML contains a
// CONFIGURATIONS_PLACEHOLDERscript marker. - Go CLI mode:
main.goembedsdist/index.htmlat compile time via//go:embed. At runtime it reads the coverage profile, collects referenced source files, gzip+base64-encodes everything, and replaces the placeholder with awindow.configs = {...}object. The result is a single portable HTML file. - Docker mode:
entrypoint.shreplaces the same placeholder withSIXTINEAI_*environment variables at container start. Nginx serves the SPA and proxies mounted volumes for live file access.
pnpm install
pnpm dev # → http://localhost:5173 with hot reloadThe config screen lets you point to a local cover.out URL during development.
# Build the single-file dist/index.html (required before go build)
pnpm build:single
# Build the Go binary
go build -o sixtine-coverage .
# Or just run directly
go run . -coverage cover.out -codebase /path/to/projectThe committed dist/index.html must be rebuilt whenever the frontend changes:
pnpm build:single
git add dist/index.htmlThis file is tracked in git so that go install works directly from the repository.




