configer is a small Go abstraction for querying and patching JSON-like
configuration trees without tying callers to one storage format.
The core module provides the configer.Config interface and an in-memory
implementation. The hujson module adapts Tailscale HuJSON, preserving comments
and formatting where the backing AST supports it.
go get github.com/asciimoth/configer/configer
go get github.com/asciimoth/configer/hujsonpackage main
import (
"fmt"
"github.com/asciimoth/configer/configer"
)
func main() {
cfg := configer.NewMemory(map[string]any{
"server": map[string]any{
"listen": ":8080",
"tls": map[string]any{
"enabled": false,
},
},
})
_ = cfg.Set(configer.Path{"server", "tls", "enabled"}, true)
tls := cfg.View(configer.Path{"server", "tls"})
enabled, _ := tls.Get(configer.Path{"enabled"})
fmt.Println(enabled)
}package main
import (
"fmt"
"github.com/asciimoth/configer/configer"
confighujson "github.com/asciimoth/configer/hujson"
)
func main() {
cfg, err := confighujson.Parse([]byte(`{
// deployment target
"deploy": {
"region": "iad",
"replicas": 2,
},
}`))
if err != nil {
panic(err)
}
_ = cfg.Set(configer.Path{"deploy", "replicas"}, 3)
_ = cfg.SetComment(configer.Path{"deploy", "replicas"}, "number of replicas")
fmt.Println(string(cfg.Pack()))
}configer.Marshal uses standard json tags and merges object fields into an
existing config. Fields omitted by omitempty leave existing values untouched.
If the config also supports comments, comment tags are written to matching
paths.
type Service struct {
Enabled bool `json:"enabled" comment:"turn service on or off"`
Mode string `json:"mode,omitempty" comment:"deployment strategy"`
}
cfg, _ := confighujson.Parse([]byte(`{
"service": {
"enabled": false,
"token": "kept"
}
}`))
_ = configer.Marshal(cfg.View(configer.Path{"service"}), Service{
Enabled: true,
Mode: "rolling",
})
var service Service
_ = configer.Unmarshal(cfg.View(configer.Path{"service"}), &service)Views are backed by the same storage and lock as the original config.
service := cfg.View(configer.Path{"service"})
readonly := service.ReadOnly()
_, _ = readonly.Get(configer.Path{"enabled"})
err := readonly.Set(configer.Path{"enabled"}, false) // configer.ErrReadOnly
_ = errFiles in this repository are distributed under the CC0 license.

To the extent possible under law,
ASCIIMoth
has waived all copyright and related or neighboring rights to
configer.