Skip to content

Go SDK

github.com/feathq/go-sdk is the Go SDK. Standard library only, no third-party dependencies. Evaluates flags locally against a polled datafile.

Terminal window
go get github.com/feathq/go-sdk

Go 1.23 or newer.

import "github.com/feathq/go-sdk/feat"
package main
import (
"context"
"fmt"
"os"
"github.com/feathq/go-sdk/feat"
)
func main() {
client, err := feat.NewClient(feat.Config{
APIKey: os.Getenv("FEAT_SERVER_KEY"),
DataPlaneURL: "https://data.feat.so",
})
if err != nil {
panic(err)
}
defer client.Close()
client.Start(context.Background())
if err := client.Ready(context.Background()); err != nil {
panic(err)
}
evalCtx := feat.EvalContext{
TargetingKey: "user-123",
Kinds: map[string]feat.ContextKindObject{
"user": {Key: "user-123", Attrs: map[string]any{
"plan": "pro",
"email": "alice@example.com",
}},
},
}
fmt.Println("checkout-v2:", client.GetBooleanValue("checkout-v2", false, evalCtx))
}

Use a server key (feat_sdk_…).

enabled := client.GetBooleanValue("checkout-v2", false, evalCtx)
variant := client.GetStringValue("hero-copy", "control", evalCtx)
limit := client.GetNumberValue("rate-limit", 100.0, evalCtx)
config := client.GetObjectValue("layout-config", defaultMap, evalCtx)
result := client.Evaluate("checkout-v2", false, evalCtx)
// result.Value, result.VariationID, result.Reason, result.ErrorMessage

Reason is one of TARGETING_MATCH, SPLIT, FALLTHROUGH, DEFAULT, DISABLED, ERROR. See Evaluation order.

  • NewClient constructs but does not start polling.
  • Start(ctx) spawns the polling goroutine. The goroutine runs until Close() is called or ctx is cancelled.
  • Ready(ctx) blocks until the first datafile arrives or the context cancels.
  • The in-memory datafile is held in an atomic.Pointer for lock-free reads.
feat.Config{
APIKey: os.Getenv("FEAT_SERVER_KEY"),
DataPlaneURL: "https://data.feat.so",
PollInterval: 30 * time.Second, // default 30s, minimum 5s
Bootstrap: serializedDatafile, // optional: skip the initial fetch
}

The Go SDK ports the same evaluation algorithm as @feathq/feat-eval bit-for-bit. The same datafile, the same context, and the same flag key always give the same result across Node.js, Go, Python, and Ruby.