Problem
The released binary is ~30 MB (stripped). This is large for a CLI documentation tool.
Root Cause
The binary is already built with -ldflags="-s -w" (debug symbols stripped), so there are no easy wins there. The size comes almost entirely from the D2 diagram library and its transitive dependencies:
| Package |
Role |
Symbols |
github.com/dop251/goja |
Full ECMAScript 5.1 JS VM — bundled by D2 |
6,597 |
oss.terrastruct.com/d2 |
Diagram compiler + SVG renderer |
1,689 |
golang.org/x/image |
Image codecs (PNG/JPEG/GIF) — pulled by D2 |
— |
github.com/golang/freetype |
Font rendering for D2 text measurement |
— |
github.com/google/pprof |
Profiling — pulled by D2 |
— |
Everything else (cobra, goldmark, chroma, fsnotify, toml) is cheap. Without D2, the binary would be roughly 8–12 MB.
Proposed Fix: Build Tag
Add //go:build d2 to internal/parser/d2.go and a no-op stub for default builds:
// internal/parser/d2_stub.go — compiled by default
//go:build !d2
package parser
import "github.com/yuin/goldmark"
func NewD2Extension() goldmark.Extender { return noopExtension{} }
// internal/parser/d2.go — only compiled with -tags d2
//go:build d2
package parser
// ... existing implementation unchanged
The D2 import in go.mod would become conditional (or stay as-is since unused imports are dead-code eliminated by the linker when the build tag excludes the file).
Default install (~10 MB):
go install github.com/engineervix/kwelea@latest
With D2 diagram support (~30 MB):
go install -tags d2 github.com/engineervix/kwelea@latest
D2 fenced blocks (```d2) in the default build would fall back to rendering as syntax-highlighted plain text.
Other Options Considered
| Option |
Savings |
Notes |
| Build tag (recommended) |
~20 MB |
Keeps feature, opt-in |
Shell out to d2 CLI |
~20 MB |
Requires separate d2 install |
| Drop D2 entirely |
~20 MB |
Cleanest; d2 blocks become code |
| UPX compression |
~40–50% |
Adds startup latency; not portable |
Acceptance Criteria
Problem
The released binary is ~30 MB (stripped). This is large for a CLI documentation tool.
Root Cause
The binary is already built with
-ldflags="-s -w"(debug symbols stripped), so there are no easy wins there. The size comes almost entirely from the D2 diagram library and its transitive dependencies:github.com/dop251/gojaoss.terrastruct.com/d2golang.org/x/imagegithub.com/golang/freetypegithub.com/google/pprofEverything else (cobra, goldmark, chroma, fsnotify, toml) is cheap. Without D2, the binary would be roughly 8–12 MB.
Proposed Fix: Build Tag
Add
//go:build d2tointernal/parser/d2.goand a no-op stub for default builds:The D2 import in
go.modwould become conditional (or stay as-is since unused imports are dead-code eliminated by the linker when the build tag excludes the file).Default install (~10 MB):
With D2 diagram support (~30 MB):
D2 fenced blocks (
```d2) in the default build would fall back to rendering as syntax-highlighted plain text.Other Options Considered
d2CLId2installAcceptance Criteria
go installproduces a binary ≤ 12 MBgo install -tags d2produces a full-featured binary (D2 diagrams work)just builduses the default (no D2) buildjust build-d2(new recipe) builds with D2 supportd2fenced blocks in default build render gracefully as code