A blazingly fast, production-ready hot reload engine for Go projects β with health checks, crash loop protection, a real-time dashboard, and more. No Air. No Realize. No hidden magic.
| Feature | Description | |
|---|---|---|
| β | Sub-2-Second Reloads | Optimized rebuild and restart pipeline |
| β | Intelligent Debouncing | Handles editor save bursts gracefully (default 300ms) |
| β | Nested Directory Support | Watches the entire project tree recursively |
| β | Graceful Process Management | Clean shutdown with SIGTERM β SIGKILL escalation |
| β | Real-Time Log Streaming | See build and server logs instantly β zero buffering |
| β | Crash Loop Protection | Exponential backoff prevents restart storms |
| Feature | Description | |
|---|---|---|
| π | Web Dashboard | Real-time build status at http://localhost:3000 |
| π₯ | HTTP Health Checks | Verify the server actually started before marking OK |
| π | Desktop Notifications | Cross-platform alerts on build success/failure |
| π§ | Build Fingerprinting | Skip rebuilds when only timestamps change |
| π | YAML Configuration | .hotreload.yaml β no more long CLI commands |
| π¨ | Beautiful Terminal Output | Color-coded, structured slog component logs |
| π | Smart Filtering | .gitignore integration + custom glob patterns |
# Clone and build
git clone https://github.com/Shiva210Jyoti/hot-reload-engine
cd hot-reload-engine
go build -o ./bin/hotreload ./cmd/hotreloadOr install directly:
go install github.com/Shiva210Jyoti/hot-reload-engine/cmd/hotreload@latesthotreload \
--root ./myproject \
--build "go build -o ./bin/server ./cmd/server" \
--exec "./bin/server"Create .hotreload.yaml in your project root:
root: ./myproject
build: go build -o ./bin/server ./cmd/server
exec: ./bin/server
debounce: 300ms
ignore_patterns:
- "**/*_test.go"
- "**/vendor/**"
health_check:
enabled: true
url: http://localhost:8080/health
timeout: 5s
interval: 500ms
max_retries: 10
notifications:
enabled: true
dashboard:
enabled: true
port: 3000Then simply run:
hotreloadmake demo
# or
./bin/hotreload --root ./testserver \
--build "go build -o ./bin/testserver ./testserver" \
--exec "./bin/testserver"In another terminal:
curl http://localhost:8080/ # β Server running - version 1.0.0
curl http://localhost:8080/health # β {"status":"ok", ...}
# Edit testserver/handler.go β save β watch auto-rebuild happen in < 2 seconds!flowchart TD
FS["π File System\n(fsnotify)"]
subgraph Coordinator["π― Coordinator β Event Orchestrator"]
direction TB
W["π Watcher\nRecursive fsnotify\n+ Smart Filter"]
DB["β± Debouncer\n300ms collapse"]
FP["π§ Fingerprinter\nSHA256 skip-opt"]
B["π¨ Builder\nexec + cancel"]
HC["π₯ HealthChecker\nHTTP poll"]
R["βΆ Runner\nProcess manager\nSIGTERMβSIGKILL"]
CT["π‘ CrashTracker\nExp. backoff"]
N["π Notifier\nDesktop alerts"]
DASH["π Dashboard\nWebSocket UI"]
end
FS -->|"OS events"| W
W -->|"FileEvent"| DB
DB -->|"one signal"| FP
FP -->|"changed?"| B
B -->|"success"| R
B -->|"failure"| N
R -->|"started"| HC
R -->|"crash"| CT
CT -->|"backoff"| R
HC -->|"healthy"| N
B -->|"events"| DASH
R -->|"events"| DASH
See docs/ARCHITECTURE.md for a deep dive into every design decision.
hot-reload-engine/
βββ cmd/hotreload/ # CLI entry point β flag parsing β Coordinator
βββ internal/
β βββ config/ # Config struct, YAML loader, defaults, validation
β βββ debouncer/ # Thread-safe time-based event debouncer
β βββ watcher/ # Recursive fsnotify wrapper + smart filter
β βββ builder/ # Build command executor with context cancellation
β β βββ fingerprint.go # SHA256 content hashing to skip redundant builds
β βββ runner/ # Child process manager
β β βββ crashloop.go # Exponential backoff crash detector
β β βββ process_unix.go # SIGTERM β SIGKILL to process group
β β βββ process_windows.go # taskkill /F /T /PID
β βββ coordinator/ # Central event orchestrator
β βββ dashboard/ # WebSocket HTTP server + embedded HTML UI
β βββ healthcheck/ # HTTP health probe with retry logic
β βββ logger/ # Custom slog handler with component labels
β βββ notifications/ # Cross-platform desktop notification (beeep)
βββ testserver/ # Sample HTTP server for demonstration
β βββ main.go # Server bootstrap + graceful shutdown
β βββ handler.go # /, /health, /crash endpoints
βββ docs/
β βββ ARCHITECTURE.md # Deep-dive design patterns
β βββ CONFIGURATION.md # Complete config file reference
β βββ TROUBLESHOOTING.md # Common issues and solutions
βββ .hotreload.yaml # Example config for the testserver
βββ Makefile
βββ go.mod
βββ README.md
hotreload [flags]
Required (or set via .hotreload.yaml):
--root string Project root directory to watch
--build string Build command e.g. "go build -o ./bin/app ."
--exec string Execute command e.g. "./bin/app"
Optional:
--debounce duration Quiet period before rebuild (default 300ms)
--ext string Comma-separated extensions to watch (default ".go")
--exclude string Comma-separated extra glob patterns to exclude
--notifications Enable desktop notifications (default true)
--dashboard Enable web dashboard on :3000
--dashboard-port int Dashboard port (default 3000)
--version Print version and exit
| Variable | Effect |
|---|---|
HOTRELOAD_LOG_LEVEL |
Set log level: DEBUG, INFO (default), WARN, ERROR |
| Metric | Value |
|---|---|
| Typical rebuild time | < 2 seconds |
| Baseline memory usage | < 50 MB |
| Max watched files | 10,000+ |
| CPU overhead (idle) | < 1% |
BenchmarkDebouncer-8 1000000 1043 ns/op
BenchmarkFingerprinter-8 5000 245631 ns/op
BenchmarkWatcher-8 10000 112458 ns/op
Run yourself:
go test -bench=. -benchmem ./...# Run all tests
go test -v ./...
# Run with race detector
go test -v -race ./...
# Generate coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
# View function-level summary
go tool cover -func=coverage.outCurrent coverage: ~85%
| Package | Scenarios |
|---|---|
debouncer |
Single trigger, rapid collapse β 1 call, spaced triggers, Stop, Benchmark |
watcher |
Single file, nested dirs, runtime-created dirs, deletions, ignore globs, shutdown, symlinks, Benchmark |
filter |
.gitignore patterns, custom globs, defaults, table-driven edge cases |
builder |
Success, failure, context cancel, real-time log streaming |
fingerprint |
Same content, changed content, new file, non-Go files, Benchmark |
runner |
Start/Stop, graceful/force shutdown, restart sequence, log streaming |
crashloop |
Single backoff, exponential levels, reset |
config |
File loading, CLI override, defaults, invalid YAML |
coordinator |
Full E2E: build β binary β file change β rebuild β shutdown |
Editors often trigger multiple filesystem events per save. Without debouncing you'd get 5β10 redundant builds per keystroke. The 300ms default is tuned for typical editor behavior.
git checkout, go mod tidy, and many SCM operations change file modification times without touching content. SHA256 fingerprinting ensures rebuilds only happen from real changes.
A typical Go server spawns goroutines that open sockets and databases. On Unix, setting Setpgid: true lets us kill the entire process tree with a single kill(-pgid). Windows uses taskkill /F /T.
Process started β server ready. A port might not be bound for 300ms after launch. Health checks poll a configured URL and only mark the server as ready after it responds with 2xx.
Rapid crash-restart loops burn CPU, make debugging harder, and are hard on OS process tables. Backoff starts at 1s and doubles (capped at 32s) β giving you time to fix the root cause.
HTTP polling creates unnecessary overhead and adds latency. A single persistent WebSocket connection lets the server push events (build start, log lines, file changes) at zero overhead.
make build # Build the hotreload binary β ./bin/hotreload
make demo # Watch the testserver with auto-reload
make test # Run the full test suite
make bench # Run benchmark suite
make clean # Remove build artifacts- ARCHITECTURE.md β Deep-dive into component design patterns
- CONFIGURATION.md β Complete
.hotreload.yamlreference - TROUBLESHOOTING.md β Common issues and solutions
MIT License β see LICENSE
Built with β€οΈ for the Go developer community