Vai (Italian: "Go!") - Because your code should go as fast as you do
Stop the endless cycle of Ctrl+C β rebuild β restart
Vai automatically rebuilds and restarts your Go applications the instant you save a file. Zero configuration, hassle and third-party dependencies.
- Get started
- Why Vai?
- Use cases
- CLI reference
- Advanced configuration
- Real examples
- How it works
- Tips and tricks
- Migrating
- Troubleshooting
- Contributing
# Install
go install github.com/sgtdi/vai@latest
# Run
vai go run .
#Your app now hot reloads on every changeNo YAML files required, no configuration or external dependencies. It just works
| Feature | Vai | Air | Fresh | Realize |
|---|---|---|---|---|
| Works out of the box | β | β | β | β |
| Zero config/flags needed | β | β | β | β |
| No external dependencies | β | β | β | β |
| CLI-first design | β | β | β | β |
| Parallel job execution | β | β | β | β |
| Built-in file watcher | β | β | β | β |
| Setup time | 5 sec | 1 min | 3 min | 5 min |
Vai is the only hot reload tool for Go that:
- Requires zero configuration to get started
- Has zero external dependencies (self-contained with built-in fswatcher)
- Works instantly - from install to hot reload in 5 seconds
- Supports complex workflows with parallel and sequential job execution (when you need it)
vai go run .Your web server restarts instantly every time you save, perfect for api development.
vai go test -v ./...Tests run automatically on every change. See results immediately.
vai --env="PORT=8080,DB_HOST=localhost,DB_USER=admin" go run .Inject environment variables without shell scripts.
# Only watch .go and .html files
vai --regex=".*\\.go$,.*\\.html$" go run ./cmd/server
# Ignore test files
vai --regex=".*\\.go$,!.*_test.go$" go run .Fine-grained control over what triggers rebuilds.
# Format then run
vai --cmd "go fmt ./..." --cmd "go run ."
# Lint, test, then run
vai --cmd "golangci-lint run" --cmd "go test ./..." --cmd "go run ."Chain commands together and run in sequence.
# Save commands to vai.yml
vai --path=./app --regex=".*\\.go$" --env="PORT=8080" --save go run .
# Then just run
vaivai [flags] [command]
USAGE:
vai go run . # Simple hot reload
vai --cmd "cmd1" --cmd "cmd2" # Multiple commands
vai # Use vai.yml config
FLAGS:
-c, --cmd string Command to run (can be used multiple times for sequential execution)
-p, --path string Path to watch for changes (default: ".")
-r, --regex string Comma-separated regex patterns for files to watch (default: ".*\\.go$,^go\\.mod$,^go\\.sum$")
-e, --env string Comma-separated KEY=VALUE pairs for environment variables
-s, --save string Save current CLI flags to a YAML configuration file
-d, --debug Enable debug mode with detailed output and create a debug.log to record watcher events
-h, --help Show this help message
EXAMPLES:
# Basic hot reload
vai go run .
# Watch specific directory
vai --path=./cmd/api go run ./cmd/api
# Custom file patterns
vai --regex=".*\\.go$,.*\\.html$,.*\\.css$" go run .
# With environment variables
vai --env="DEBUG=true,PORT=3000" go run .
# Chain multiple commands
vai --cmd "go generate ./..." --cmd "go run ."
# Save configuration to vai.yml
vai --path=./app --env="ENV=dev" --save go run ./app
For complex projects with multiple workflows, you can create a vai.yml file, that will be automatically detect and used.
config:
clearCli: true # Clear screen before each reload
jobs:
# Main application
run-app:
trigger:
regex:
- ".*\\.go$"
- "!.*_test.go$" # Exclude test files
series:
- cmd: "go fmt ./..."
- cmd: "go run ."
# Run tests when test files change
test:
trigger:
paths:
- . # Entrypoint to watch for changes, multiple paths can be specified
regex:
- ".*_test\\.go$"
series:
- cmd: "go test -v ./..."config:
severity: info # Set logging level: debug, info, warn, error (default: warn)
clearCli: true
cooldown: 200ms
jobs:
# Development server
dev-server:
trigger:
regex:
- ".*\\.go$"
- "!.*_test.go$"
- ".*\\.html$"
- ".*\\.css$"
series:
- cmd: "go fmt ./..."
- cmd: "go run ./cmd/server"
env:
- "ENV=development"
- "PORT=8080"
# Quality checks (runs in parallel)
quality:
trigger:
regex:
- ".*_test\\.go$"
parallel: # All commands run simultaneously
- cmd: "go test -v -race ./..."
- cmd: "go vet ./..."
- cmd: "golangci-lint run --fast"
- cmd: "staticcheck ./..."
# Assets pipeline
assets:
trigger:
regex:
- ".*\\.scss$"
- ".*\\.js$"
series:
- cmd: "npm run build:css"
- cmd: "npm run build:js"config:
severity: warn # Logging level: debug, info, warn, error (default: warn)
clearCli: false # Clear terminal before running jobs (default: false)
cooldown: 100ms # Wait time after file change to prevent duplicate triggers
batchingDuration: 1s # Group multiple rapid changes into single trigger
bufferSize: 4096 # Event buffer size for high-velocity changesComplete working examples are in the examples/ directory:
| Example | Description | Use Case |
|---|---|---|
| simple-test | Auto-run tests on file changes | TDD workflow |
| build-and-run | Build binary then execute | Production-like workflow |
| web-server | Hot reload web application | Web development |
| advanced-workflow | Parallel jobs & complex pipelines | Enterprise projects |
Each example includes:
- Complete
vai.ymlconfiguration - Sample Go application
- Detailed README with instructions
Vai uses a custom-built file watcher called fswatcher that monitors your project for changes. When a file matching your patterns is modified:
- Event Detection: fswatcher detects the file change
- Debouncing: Vai waits for the cooldown period (default 100ms) to batch rapid changes
- Job Matching: Finds all jobs with regex patterns matching the changed file
- Execution: Runs matched jobs (series = sequential, parallel = simultaneous)
- Process Management: Cleanly stops the old process and starts the new one
This architecture means:
- β‘ Fast: No external process spawning overhead
- π― Reliable: Purpose-built file watcher with proven stability
- π Safe: Proper process cleanup prevents zombie processes
- π¦ Simple: Everything in one binary
config:
cooldown: 200ms # Wait 200ms after last change
batchingDuration: 500ms # Group changes within 500ms windowUseful when your editor saves multiple files simultaneously.
vai --path=./internal go run ./cmd/apiIgnore changes outside your main source directory.
vai --debug go run .Shows exactly which files are being watched and which events trigger rebuilds.
jobs:
app:
trigger:
regex:
- ".*\\.go$"
- "!.*\\.pb\\.go$" # Exclude protobuf generated files
- "!.*_gen\\.go$" # Exclude go:generate output
- "!vendor/.*" # Exclude vendor directory# Development
vai --env="ENV=dev,DB_HOST=localhost" go run .
# Staging (save to vai.staging.yml)
vai --env="ENV=staging,DB_HOST=staging.db" --save=vai.staging.yml go run .
# Use staging config
vai -f vai.staging.ymlAir requires air.toml:
[build]
cmd = "go build -o ./tmp/main ."
bin = "./tmp/main"
include_ext = ["go", "html"]Vai needs nothing:
vai go run .Or with equivalent config:
jobs:
app:
trigger:
regex: [".*\\.go$", ".*\\.html$"]
series:
- cmd: "go run ."Fresh requires runner.conf:
root: .
tmp_path: ./tmp
build_name: runner-build
build_log: runner-build-errors.log
Vai needs nothing:
vai go run .Check your regex patterns:
vai --debug go run . # Shows which files are watchedIncrease buffer size for large projects:
config:
bufferSize: 8192Some editors save via rename/delete, just adjust cooldown:
config:
cooldown: 300msVai sends SIGTERM (Unix) or taskkill (Windows) to processes. If your app doesn't handle shutdown gracefully:
// Add signal handling to your main.go
func main() {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
// Your application code
<-ctx.Done()
// Cleanup
}Reduce file system events:
config:
cooldown: 500ms # Higher cooldown
batchingDuration: 1s # Batch events
jobs:
app:
trigger:
regex:
- "internal/.*\\.go$" # Watch only specific dirs
- "!vendor/.*" # Exclude vendor
- "!node_modules/.*" # Exclude node_modulesContributions are welcome! Help making Vai better.
- π Report bugs - Open an issue
- π‘ Suggest features - Start a discussion
- π Improve docs - Submit a PR with documentation fixes
- π§ Submit PRs - Check CONTRIBUTING.md for guidelines
- β Star the repo - Helps others discover Vai