Skip to content

Instantly share code, notes, and snippets.

@aurelijusb
Last active January 4, 2026 14:35
Show Gist options
  • Select an option

  • Save aurelijusb/e3d0a3222eb26b35c365a53afe2ab6a3 to your computer and use it in GitHub Desktop.

Select an option

Save aurelijusb/e3d0a3222eb26b35c365a53afe2ab6a3 to your computer and use it in GitHub Desktop.
GrowthBook Open Feature GO example

Assuming you have GrowthBook running locally via docker-compose

Usage

go run main.go

Example response

2026/01/04 16:35:12 INFO Starting source="Growthbook polling datasource"
2026/01/04 16:35:12 INFO Loading features
2026/01/04 16:35:12 INFO First load finished source="Growthbook polling datasource"
2026/01/04 16:35:12 INFO Started source="Growthbook polling datasource"
2026/01/04 16:35:12 userContext: {
  "id": "d6e3a41b801cf06f7f942cfa9fab309f"
}
2026/01/04 16:35:12 Viewed Experiment
2026/01/04 16:35:12 Hook: {}
2026/01/04 16:35:12 Result: {
  "Value": true,
  "FlagKey": "feature1",
  "FlagType": 0,
  "Variant": "fr_1j14ku1omjwrctju",
  "Reason": "TARGETING_MATCH",
  "ErrorCode": "",
  "ErrorMessage": "",
  "FlagMetadata": {
    "experiment": true,
    "source": "experiment"
  }
}
2026/01/04 16:35:12 Extra: {}
2026/01/04 16:35:12 feature is on
2026/01/04 16:35:12 Viewed Experiment
2026/01/04 16:35:12 Hook: {}
2026/01/04 16:35:12 Result: {
  "Value": true,
  "FlagKey": "feature1",
  "FlagType": 0,
  "Variant": "fr_1j14ku1omjwrctju",
  "Reason": "TARGETING_MATCH",
  "ErrorCode": "",
  "ErrorMessage": "",
  "FlagMetadata": {
    "experiment": true,
    "source": "experiment"
  }
}
2026/01/04 16:35:12 Extra: {}
2026/01/04 16:35:12 feature details: {
  "Value": true,
  "FlagKey": "feature1",
  "FlagType": 0,
  "Variant": "fr_1j14ku1omjwrctju",
  "Reason": "TARGETING_MATCH",
  "ErrorCode": "",
  "ErrorMessage": "",
  "FlagMetadata": {
    "experiment": true,
    "source": "experiment"
  }
}
{
"status": 200,
"features": {
"feature1": {
"defaultValue": false,
"rules": [
{
"id": "fr_1j14ku1omjwr8e5i",
"condition": {
"id": "force1"
},
"force": true
},
{
"id": "fr_1j14ku1omjwrctju",
"coverage": 1,
"hashAttribute": "id",
"seed": "aab6cb2c-5bdb-4081-9bf3-849b69e11025",
"hashVersion": 2,
"variations": [
false,
true
],
"weights": [
0.5,
0.5
],
"key": "myTrackingKey",
"meta": [
{
"key": "0",
"name": "Control"
},
{
"key": "1",
"name": "Variation"
}
],
"phase": "0",
"name": "Experiemnt"
}
]
}
},
"dateUpdated": "2026-01-02T12:47:29.283Z"
}
module github.com/aurelijusb/fleature-flag-tests-of-gb-go
go 1.25.5
require github.com/growthbook/growthbook-golang v0.2.6
require (
github.com/go-logr/logr v1.4.3 // indirect
github.com/growthbook/growthbook-openfeature-provider-go v0.0.3 // indirect
github.com/open-feature/go-sdk v1.17.0 // indirect
github.com/tmaxmax/go-sse v0.10.0 // indirect
go.uber.org/mock v0.6.0 // indirect
)
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/growthbook/growthbook-golang v0.2.6 h1:A6hclPLrtOYnleZ/yQUejCbUR5fQ4waDvwJb+oA8lEg=
github.com/growthbook/growthbook-golang v0.2.6/go.mod h1:mY8oBSateRALL7hMwr8UaPmsdm+10ffmgWIT1N5iQZE=
github.com/growthbook/growthbook-openfeature-provider-go v0.0.3 h1:6U4ylXJuPcFvvy5UUKb4s7uMZM0dkhqzdB4kcxLLxyY=
github.com/growthbook/growthbook-openfeature-provider-go v0.0.3/go.mod h1:9e+m2LD9ggZ9dTAucOeLgWVI0Ahhe2ph4GbNgcPYHWc=
github.com/open-feature/go-sdk v1.17.0 h1:/OUBBw5d9D61JaNZZxb2Nnr5/EJrEpjtKCTY3rspJQk=
github.com/open-feature/go-sdk v1.17.0/go.mod h1:lPxPSu1UnZ4E3dCxZi5gV3et2ACi8O8P+zsTGVsDZUw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tmaxmax/go-sse v0.10.0 h1:j9F93WB4Hxt8wUf6oGffMm4dutALvUPoDDxfuDQOSqA=
github.com/tmaxmax/go-sse v0.10.0/go.mod h1:u/2kZQR1tyngo1lKaNCj1mJmhXGZWS1Zs5yiSOD+Eg8=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
package main
import (
"context"
"crypto/rand"
"encoding/hex"
"encoding/json"
"log"
"time"
gb "github.com/growthbook/growthbook-golang"
gbprovider "github.com/growthbook/growthbook-openfeature-provider-go"
"github.com/open-feature/go-sdk/openfeature"
)
type MyHook struct {
openfeature.UnimplementedHook
}
func randomID() string {
b := make([]byte, 16)
_, _ = rand.Read(b)
return hex.EncodeToString(b)
}
func (h MyHook) After(ctx context.Context, hookContext openfeature.HookContext, flagEvaluationDetails openfeature.InterfaceEvaluationDetails, hookHints openfeature.HookHints) error {
log.Println("Viewed Experiment")
hook, _ := json.MarshalIndent(hookContext, "", " ")
revaluation, _ := json.MarshalIndent(flagEvaluationDetails, "", " ")
hints, _ := json.MarshalIndent(hookHints, "", " ")
log.Println("Hook:", string(hook))
log.Println("Result:", string(revaluation))
log.Println("Extra:", string(hints))
return nil
}
func main() {
ctx := context.TODO()
gbClient, err := gb.NewClient(context.Background(),
gb.WithApiHost("http://localhost:3100"),
gb.WithClientKey("sdk-iyhSNglT6juJSHl"),
gb.WithPollDataSource(30*time.Second),
)
if err != nil {
log.Fatalf("Failed to create GrowthBook client: %v", err)
}
provider := gbprovider.NewProvider(gbClient)
openfeature.SetProviderAndWait(provider)
client := openfeature.NewClient("app")
client.AddHooks(MyHook{})
// User context
id := randomID() // replace with "force1" to test forced behavior
attrs := openfeature.NewEvaluationContext(
id,
map[string]any{
"id": id,
},
)
attrsJSON, _ := json.MarshalIndent(attrs.Attributes(), "", " ")
log.Println("userContext:", string(attrsJSON))
featureName := "feature1" // change to test missing feature
if client.Boolean(ctx, featureName, false, attrs) {
log.Println("feature is on")
} else {
log.Println("feature is off")
}
details, err := client.BooleanValueDetails(ctx, featureName, false, attrs)
if err != nil {
log.Fatal("Error evaluating feature:", err)
}
detailsJSON, _ := json.MarshalIndent(details, "", " ")
log.Println("feature details:", string(detailsJSON))
// give async callbacks time in very short-lived runs
time.Sleep(100 * time.Millisecond)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment