A small, fast, cross-platform file watcher + rebuilder + runner for Go projects.
- Zero-config default. Runs on any Go module with
gow— watches the tree, builds withgo build, runs the output binary, restarts on change. - Sensible filtering. Only
.gofiles trigger rebuilds by default. Deny-list covers.git,node_modules,dist,bin,.idea,.vscodeautomatically. - Debounced. Rapid bursts of writes (atomic-save editors,
gofmt) coalesce into one rebuild. - Clean shutdown.
Ctrl+Cinterrupts the target process group before exiting — no orphaned children. - Cross-platform. Uses fsnotify; Unix signal group handling via build tags.
go install github.com/rw3iss/gow@latestOr from source:
git clone https://github.com/rw3iss/gow.git
cd gow
go installFrom any Go module directory:
gowThis watches ./**/*.go, runs go build, then runs ./<modulename>. Restarts on every relevant change.
# Run via `go run` instead of the built binary.
gow -run "run main.go"
# Watch a subdirectory and run a pre-built binary elsewhere.
gow -dir ./server/api -run "./bin/api"
# Pass extra build flags.
gow -build "build -race -tags dev"
# Verbose mode — logs every filesystem event and debounce decision.
gow -debug| Flag | Default | Purpose |
|---|---|---|
-config <path> |
auto (./config.json if any) |
Path to optional config.json |
-dir <path> |
current working directory | Directory to watch + build in |
-run <cmd> |
./<workdir-basename> |
Run command. Starts with ./ or / → exec directly. Otherwise treated as go <args>. |
-build <cmd> |
build |
go <cmd> to invoke for builds |
-debug |
off | Verbose logging |
-v, -version |
— | Print version |
-h, -help |
— | Help |
Config is fully optional. Place a config.json in the working directory (or point at one with -config) to override any default. All keys are optional:
{
"watchDir": "./",
"buildCommand": "build",
"runCommand": "./myapp",
"extensions": [".go", ".tmpl"],
"denyFragments": [".git", "node_modules", "dist"],
"debounceMs": 200
}| Key | Type | Default |
|---|---|---|
watchDir |
string | workdir |
buildCommand |
string | "build" — passed to go as subcommand + args |
runCommand |
string | "./<workdir-basename>" — exec'd directly if it starts with ./ or /, else passed to go |
extensions |
[]string | [".go"] — allow-list of extensions that trigger rebuild |
denyFragments |
[]string | [".git", "node_modules", "dist", "bin", ".idea", ".vscode", ".cache", ".swp", "~"] |
debounceMs |
int | 200 — coalesce bursts of events into one rebuild |
CLI flags always win over config; config always wins over defaults.
main.go Entry point. Parses flags, wires Application.
lib/
Application.go Central bus. Owns lifecycle + signal handling.
Builder.go Wraps `go build`. Returns exec errors cleanly.
Runner.go Owns the child process. Smart exec (./bin vs go).
Watcher.go fsnotify wrapper with filter + debounce.
proc_unix.go Process-group setup for clean teardown (Unix).
proc_windows.go No-op stub (Windows lacks POSIX process groups).
utils/
Colors.go ANSI color constants.
Config.go JSON config loader. Missing file is benign.
Convert.go Array-of-interface → []string helper.
FormatWriter.go io.Writer wrapper that prefixes output.
Log.go Log / Debug / LogError.
test/
test.go Trivial target for manually smoke-testing gow.
- Ctrl+C leaves a child process running. Shouldn't happen since 2026-04 — if you still see it, run with
-debugto see the teardown sequence and file an issue. Known limitation: Windows doesn't have POSIX process groups so a grandchild that ignorestaskkillmay outlive gow. - Rebuild fires on my editor's swap file. Add the swap suffix to
denyFragments, or extendextensionsto be stricter. - My rebuild runs twice per save. Your editor is writing the file multiple times. The default 200ms debounce should catch most of this — increase
debounceMsif not.
The lib/ packages are public and usable from other Go code:
import "github.com/rw3iss/gow/lib"
app := lib.NewApplication(lib.Options{
WorkDir: "/path/to/project",
RunCommand: "run main.go",
DebugEnabled: true,
})
app.Init() // blocks until signalUseful for embedding a live-reload loop in a larger tool (test harnesses, IDE integrations).
