Watch files like a pro.
A high-performance, composable file system watcher built on fsnotify. Automatic recursion, 17+ filters, 18 middleware, and production-grade resilience.
package main
import (
"context"
"fmt"
"log"
"time"
filewatcher "github.com/larsartmann/go-filewatcher/v2"
)
func main() {
w, err := filewatcher.New(
[]string{"./src"},
filewatcher.WithExtensions(".go"),
filewatcher.WithDebounce(500*time.Millisecond),
)
if err != nil { log.Fatal(err) }
defer w.Close()
events, _ := w.Watch(context.Background())
// channel of Event{Path, Op, Timestamp, ...}
for ev := range events {
fmt.Printf("%s: %s\n", ev.Op, ev.Path)
}
} Everything you need to watch files.
17+ composable filters, 18 production middleware, and resilience built for large-scale filesystems.
Zero Boilerplate
Start watching in 5 lines of code. Sensible defaults, automatic recursion, context-aware cancellation.
17+ Built-in Filters
Extensions, globs, regex, size, age, content hash, gitignore, generated-code detection. Compose with AND/OR/NOT.
18 Middleware
Logging, recovery, rate limiting, circuit breaker, metrics, batching, error correlation, exponential backoff.
Resilient by Default
Self-healing watches, inotify budget awareness, graceful ENOSPC handling, and .gitignore-aware walking.
Full Observability
Built-in Stats(), Prometheus collector, OpenTelemetry tracing middleware, and structured debug logging.
NFS/FUSE Friendly
Optional polling mode supplements OS-native events for network filesystems, Docker volumes, and FUSE mounts.
Create. Watch. Consume.
Four steps from zero to streaming file events. No boilerplate, no manual goroutine management.
Create
Initialize with paths and options. Functional options configure filters, middleware, debounce.
w, _ := filewatcher.New(paths,
filewatcher.WithExtensions(".go"),
) Watch
Call Watch(ctx) to start. Returns a read-only event channel. Goroutines handle the rest.
events, _ := w.Watch(ctx) Pipeline
Events pass through your filter chain and middleware. 17+ filters, 18 middleware, composable.
// filters + middleware applied automatically Consume
Range over the channel. Each event carries path, op, timestamp, size, modtime, and optional hash.
for ev := range events {
fmt.Println(ev.Op, ev.Path)
} Why go-filewatcher?
Raw fsnotify gives you events and nothing else. Other wrappers give you some convenience. go-filewatcher gives you production-grade infrastructure.
| Raw fsnotify | Other wrappers | go-filewatcher | |
|---|---|---|---|
| Recursive watching | ~ | ||
| Built-in filters | ~ | ||
| Middleware chains | |||
| Debouncing | ~ | ||
| .gitignore-aware | |||
| ENOSPC resilience | |||
| NFS/FUSE polling | |||
| Prometheus + OTel | |||
| Self-healing |
Built for real workloads.
Drop it into any system that needs to react to filesystem changes.
Hot Reload
Dev servers, build systems, and live-reload tools that trigger on file changes
Log Monitoring
Tail and process log files in real-time with debouncing and rate limiting
CI/CD Triggers
Watch for changes and trigger pipelines, tests, or deployments automatically
Start watching in minutes.
One import. Zero boilerplate. Production-ready.