Essential information for AI agents and developers working with the GO Feature Flag codebase.
π‘ Important: The Makefile is the easiest way to interact with this repository. Use
make helpto see all commands.
Most Common Commands:
make workspace-init # Initialize Go workspace (required for monorepo)
make vendor # Vendor dependencies
make test # Run all tests
make build # Build all binaries
make lint # Run linter
make watch-doc # Start documentation server
make help # Show all available commandsGO Feature Flag is a lightweight, open-source feature flagging solution written in Go. This repository is a monorepo using Go workspaces.
Key Features:
- Feature flag implementation with OpenFeature standard support
- Multiple storage backends (S3, HTTP, Kubernetes, MongoDB, Redis, GCS, Azure, PostgreSQL, etc.)
- Complex rollout strategies (A/B testing, progressive, scheduled)
- Data export, notification, and tracking systems
OpenFeature SDKs β Relay Proxy (cmd/relayproxy/) β GO Module (ffclient)
β
Retriever Manager β Cache Manager β Notifier Service / Exporter Manager
Data Flow: Retrievers fetch configs β Cache stores flags β Change detection triggers Notifiers β Evaluation generates Events β Exporters send data
Key Components:
ffclient(root package): Core Go module for direct integration (root.gofiles arepackage ffclient)cmd/relayproxy/: HTTP API server (uses Echo + Zap logging)retriever/: Flag configuration sources (File, HTTP, S3, K8s, MongoDB, Redis, GitHub, GitLab, Bitbucket, PostgreSQL, Azure Blob Storage, GCS)exporter/: Data export destinations (S3, File, Kafka, Kinesis, Webhook, GCS, Pub/Sub, SQS, Azure, Logs, OpenTelemetry)notifier/: Change notifications (Slack, Webhook, Discord, Microsoft Teams, Logs)modules/core: Core logic module used by OpenFeature providers and WASM
Root Level:
- Root
.gofiles: Coreffclientpackage (variation.go,feature_flag.go,config.go,tracking.go,variation_all_flags.go,config_exporter.go) cmd/: Applications (relayproxy, cli, lint, editor, jsonschema-generator, wasm)retriever/,exporter/,notifier/: Integration packagesmodules/: Separate Go modules (coreonly)internal/: Internal packages (cache, flagstate, notification, signer)ffcontext/: Evaluation context packageffuser/: User context (legacy)model/: DTO modelscmdhelpers/: Shared CLI helpers (errors, retriever config)utils/: Utilities (fflog, string helpers, constants)openfeature/providers/: In-repo providers (Kotlin, Python, PHP, Ruby, Swift)openfeature/provider_tests/: Integration tests for providers (Go, JS, Java, .NET)testutils/,testdata/,examples/,website/
Key Files:
variation.go: Flag evaluation methodsvariation_all_flags.go: Bulk evaluation of all flagsfeature_flag.go: Core logic and initializationconfig.go: Configuration structureconfig_exporter.go: Exporter configurationtracking.go: Tracking/experimentation supportMakefile: Primary interface (usemake help)
Flag Evaluation Flow:
- Init β Retrievers fetch configs β Cache stores β Polling refreshes
- Change detection β Notifiers triggered β Evaluation β Events exported
Flag Format: YAML/JSON/TOML with variations, targeting rules, and defaultRule
Evaluation Context: Targeting key (required), custom attributes, optional bucketing key
Interfaces:
Retriever:Retrieve(ctx context.Context) ([]byte, error)Exporter:Export(context.Context, *fflog.FFLogger, []ExportableEvent) error+IsBulk() boolNotifier:Notify(cache DiffCache) error
Adding Retriever/Exporter/Notifier:
- Create package in respective directory
- Implement interface
- Add config struct
- Register in manager
- Add table-driven tests
- Update docs
OpenFeature Providers:
- Most providers in OpenFeature contrib repos (Go, JS, Java, .NET)
- In this repo: Kotlin (
kotlin-provider/), Python (python-provider/), PHP (php-provider/), Ruby (ruby-provider/), Swift (swift-provider/) - Providers use
modules/corefor evaluation logic
Modules (modules/core):
- Core logic separated for reuse by OpenFeature providers and WASM module
modules/core: Flag structures, context, models, utilities- Allows independent versioning and smaller dependency trees
PR Policy: Must use .github/PULL_REQUEST_TEMPLATE.md. Fill all sections, link issues, complete checklist, include tests. PR titles should use a semantic commit prefix.
Style: Table-driven tests (test array style) - standard Go pattern
func TestFunction(t *testing.T) {
tests := []struct {
name string
args args
want expectedType
wantErr assert.ErrorAssertionFunc
}{...}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// test logic with assert.Equal, assert.NoError, etc.
})
}
}Commands: make test, make coverage, make bench, make provider-tests
Coverage: Aim for 90%+, use testify/assert, mock external deps
Initialization:
ffclient.Init(ffclient.Config{
PollingInterval: 3 * time.Second,
Retriever: &httpretriever.Retriever{URL: "..."},
})
defer ffclient.Close()Evaluation:
user := ffcontext.NewEvaluationContext("user-key")
value, _ := ffclient.BoolVariation("flag-name", user, false)Logging:
- Go Module: Uses
slog(utils/fflog/) - structured logging - Relay Proxy: Uses Echo + Zap (
cmd/relayproxy/log/,api/middleware/zap.go) - request logging
Error Handling: Always return errors, never panic. Use default values on failure.
π‘ Use Makefile for all tasks -
make helpshows all commands
Setup:
make workspace-init # Initialize Go workspace (monorepo requirement)
make vendor # Vendor dependencies
pre-commit install # Install pre-commit hooksCommon Commands:
- Build:
make build,make build-relayproxy,make build-cli,make build-wasm,make build-wasi,make build-editor-api,make build-jsonschema-generator,make build-modules - Dev:
make watch-relayproxy,make watch-doc,make serve-doc - Test:
make test,make coverage,make bench,make provider-tests - Quality:
make lint,make tidy,make vendor - Utils:
make clean,make swagger,make generate-helm-docs,make bump-helm-chart-version,make bump-wasm-contrib
Code Quality:
- Use
make lint(golangci-lint) - Write table-driven tests
- Update docs for user-facing changes
Flag Evaluation: variation.go β feature_flag.go β internal/cache/ β internal/flagstate/
API Endpoints: cmd/relayproxy/api/routes_*.go β controller/ β model/
Configuration: config.go (ffclient), cmd/relayproxy/config/config.go (relay proxy)
Flag Format: .schema/flag-schema.json, testdata/flag-config.*, https://gofeatureflag.org/docs
Makefile: Primary interface -make helpfor commandsgo.mod: Dependencies (monorepo withmodules/core,cmd/wasm).golangci.yml: Linter configCONTRIBUTING.md: Contribution guidelines.github/PULL_REQUEST_TEMPLATE.md: PR template (required)
Key Libraries: Echo (HTTP), Koanf (config), OpenTelemetry (observability), Prometheus (metrics), Testcontainers (integration tests)
Monorepo Modules (Go workspace):
- Main module (root): Core
ffclientlibrary modules/core: Core data structures (used by providers/WASM/relayproxy)cmd/wasm: WebAssembly/WASI evaluation
- Documentation: https://gofeatureflag.org/docs
- Examples:
examples/directory - API Docs:
cmd/relayproxy/docs/ - OpenFeature: https://openfeature.dev
Entry Points: ffclient.Init(), cmd/relayproxy/main.go, cmd/cli/main.go
Interfaces: Retriever, Exporter, Notifier, Cache
Config: YAML/JSON/TOML flags, ffclient.Config, cmd/relayproxy/config/config.go
Critical Rules:
- Never commit secrets - No API keys, passwords, tokens, or credentials in code or config files
- Ask before adding dependencies - Always request approval before adding new packages to
go.mod - Don't touch vendor directories - Never modify
vendor/directory directly (usemake vendorinstead) - Don't modify
go.workmanually - Usemake workspace-initfor workspace setup - Don't force push to main/master - Always work on feature branches
Note: This is a living document. Update as the codebase evolves!