Skip to content

Instantly share code, notes, and snippets.

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

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

Select an option

Save aurelijusb/c1ba52d2e4f8c0bd537bd53e3776df26 to your computer and use it in GitHub Desktop.
GrowthBook native GO SDK example

Assuming you have GrowthBook running locally via docker-compose

Usage

go run main.go

Example response

2026/01/04 16:29:03 INFO Starting source="Growthbook polling datasource"
2026/01/04 16:29:03 INFO Loading features
2026/01/04 16:29:03 INFO First load finished source="Growthbook polling datasource"
2026/01/04 16:29:03 INFO Started source="Growthbook polling datasource"
2026/01/04 16:29:03 userContext: {
  "id": "02ae0723732ed10a0131ba519d3e1c98"
}
2026/01/04 16:29:03 Viewed Experiment
2026/01/04 16:29:03 Experiment: {
  "key": "myTrackingKey",
  "variations": [
    false,
    true
  ],
  "weights": [
    0.5,
    0.5
  ],
  "active": null,
  "coverage": 1,
  "ranges": null,
  "condition": {},
  "parentConditions": null,
  "namespace": null,
  "force": null,
  "hashAttribute": "id",
  "fallbackAttribute": "",
  "hashVersion": 2,
  "meta": [
    {
      "key": "0",
      "name": "Control",
      "passthrough": false
    },
    {
      "key": "1",
      "name": "Variation",
      "passthrough": false
    }
  ],
  "filters": null,
  "seed": "aab6cb2c-5bdb-4081-9bf3-849b69e11025",
  "name": "Experiemnt",
  "phase": "0",
  "disableStickyBucketing": false,
  "bucketVersion": 0,
  "minBucketVersion": 0
}
2026/01/04 16:29:03 Result: {
  "inExperiment": true,
  "variationId": 0,
  "value": false,
  "hashUsed": true,
  "hashAttribute": "id",
  "hashValue": "02ae0723732ed10a0131ba519d3e1c98",
  "featureId": "feature1",
  "key": "0",
  "bucket": 0.1083,
  "name": "Control",
  "passthrough": false,
  "stickyBucketUsed": false
}
2026/01/04 16:29:03 Extra: <nil>
2026/01/04 16:29:03 feature is off
2026/01/04 16:29:03 feature details: {
  "ruleId": "fr_1j14ku1omjwrctju",
  "value": false,
  "source": "experiment",
  "on": false,
  "off": true,
  "experiment": {
    "key": "myTrackingKey",
    "variations": [
      false,
      true
    ],
    "weights": [
      0.5,
      0.5
    ],
    "active": null,
    "coverage": 1,
    "ranges": null,
    "condition": {},
    "parentConditions": null,
    "namespace": null,
    "force": null,
    "hashAttribute": "id",
    "fallbackAttribute": "",
    "hashVersion": 2,
    "meta": [
      {
        "key": "0",
        "name": "Control",
        "passthrough": false
      },
      {
        "key": "1",
        "name": "Variation",
        "passthrough": false
      }
    ],
    "filters": null,
    "seed": "aab6cb2c-5bdb-4081-9bf3-849b69e11025",
    "name": "Experiemnt",
    "phase": "0",
    "disableStickyBucketing": false,
    "bucketVersion": 0,
    "minBucketVersion": 0
  },
  "experimentResult": {
    "inExperiment": true,
    "variationId": 0,
    "value": false,
    "hashUsed": true,
    "hashAttribute": "id",
    "hashValue": "02ae0723732ed10a0131ba519d3e1c98",
    "featureId": "feature1",
    "key": "0",
    "bucket": 0.1083,
    "name": "Control",
    "passthrough": false,
    "stickyBucketUsed": false
  }
}
2026/01/04 16:29:03 INFO Closing source="Growthbook polling datasource"
{
"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-gb-go
go 1.25.5
require github.com/growthbook/growthbook-golang v0.2.6
require github.com/tmaxmax/go-sse v0.10.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/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/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=
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"
)
func randomID() string {
b := make([]byte, 16)
_, _ = rand.Read(b)
return hex.EncodeToString(b)
}
func main() {
ctx := context.TODO()
client, err := gb.NewClient(
ctx,
gb.WithApiHost("http://localhost:3100"),
gb.WithClientKey("sdk-iyhSNglT6juJSHl"),
gb.WithPollDataSource(30*time.Second),
gb.WithExperimentCallback(func(
ctx context.Context,
experiment *gb.Experiment,
result *gb.ExperimentResult,
extra any,
) {
log.Println("Viewed Experiment")
exp, _ := json.MarshalIndent(experiment, "", " ")
res, _ := json.MarshalIndent(result, "", " ")
log.Println("Experiment:", string(exp))
log.Println("Result:", string(res))
log.Println("Extra:", extra)
}),
)
if err != nil {
log.Fatal(err)
}
defer client.Close()
if err := client.EnsureLoaded(context.TODO()); err != nil {
log.Fatal("Client data load failed", "error", err)
}
// User context
attrs := gb.Attributes{
"id": randomID(), // replace with "force1" to test forced behavior
}
attrsJSON, _ := json.MarshalIndent(attrs, "", " ")
log.Println("userContext:", string(attrsJSON))
scoped, err := client.WithAttributes(attrs)
if err != nil {
log.Fatal(err)
}
featureName := "feature1" // change to test missing feature
details := scoped.EvalFeature(ctx, featureName)
if details.On {
log.Println("feature is on")
} else {
log.Println("feature is off")
}
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