uconfig-watchfiles
March 31, 2026 ยท View on GitHub
File watching extension for uconfig. Add watchfiles.New() to your plugins and call Watch for automatic config reload when source files change.
Usage
package main
import (
"context"
"encoding/json"
"fmt"
"os"
"os/signal"
"github.com/omeid/uconfig"
"github.com/omeid/uconfig/plugins/file"
watchfiles "github.com/omeid/uconfig-watchfiles"
)
type Config struct {
Hosts []string `default:"localhost" usage:"bind addresses"`
Mode string `default:"start" flag:",command" usage:"start|stop"`
}
var files = uconfig.Files{
{Path: file.Relative("config.json"), Unmarshal: json.Unmarshal, Optional: true},
}
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
defer cancel()
conf := uconfig.Classic[Config](files, watchfiles.New())
err := conf.Watch(ctx, func(ctx context.Context, c *Config) error {
fmt.Printf("config loaded: %+v\n", c)
// Block until told to reload or stop.
<-ctx.Done()
return nil
// Return nil to exit Watch cleanly.
// Return any other error to abort.
})
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
The callback is called once with the initial config, then again whenever a config file changes. Changes are debounced (200ms). When a file changes, the callback's context is cancelled, the full config is re-parsed (preserving env, flags, and other sources), and the callback is called again with the new value.
watchfiles.New() is a uconfig Extension plugin. It discovers file paths from sibling file plugins and watches them with fsnotify. One watcher handles all files.
Install
go get github.com/omeid/uconfig-watchfiles
LICENSE
MIT.