{"id":20607713,"url":"https://github.com/open-feature/go-sdk","last_synced_at":"2026-01-16T07:59:22.660Z","repository":{"id":39851111,"uuid":"486747055","full_name":"open-feature/go-sdk","owner":"open-feature","description":"Go SDK for OpenFeature","archived":false,"fork":false,"pushed_at":"2025-03-30T15:02:19.000Z","size":446,"stargazers_count":164,"open_issues_count":8,"forks_count":39,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-01T10:11:52.311Z","etag":null,"topics":["go","golang","openfeature","sdk"],"latest_commit_sha":null,"homepage":"https://openfeature.dev","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/open-feature.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-04-28T21:00:52.000Z","updated_at":"2025-03-27T19:18:04.000Z","dependencies_parsed_at":"2023-07-13T05:55:06.548Z","dependency_job_id":"5cc73ab3-24ae-4ee5-a2ad-d27aadba1482","html_url":"https://github.com/open-feature/go-sdk","commit_stats":{"total_commits":224,"total_committers":27,"mean_commits":8.296296296296296,"dds":0.7098214285714286,"last_synced_commit":"73c0e85795c8c0a0ccb70c7d3babee0f3c8e2fd5"},"previous_names":["open-feature/golang-sdk"],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-feature%2Fgo-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-feature%2Fgo-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-feature%2Fgo-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/open-feature%2Fgo-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/open-feature","download_url":"https://codeload.github.com/open-feature/go-sdk/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247829512,"owners_count":21002997,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","openfeature","sdk"],"created_at":"2024-11-16T10:08:23.155Z","updated_at":"2026-01-16T07:59:22.653Z","avatar_url":"https://github.com/open-feature.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- markdownlint-disable MD033 --\u003e\n\u003c!-- x-hide-in-docs-start --\u003e\n\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/open-feature/community/0e23508c163a6a1ac8c0ced3e4bd78faafe627c7/assets/logo/horizontal/white/openfeature-horizontal-white.svg\" /\u003e\n    \u003cimg align=\"center\" alt=\"OpenFeature Logo\" src=\"https://raw.githubusercontent.com/open-feature/community/0e23508c163a6a1ac8c0ced3e4bd78faafe627c7/assets/logo/horizontal/black/openfeature-horizontal-black.svg\" /\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003ch2 align=\"center\"\u003eOpenFeature Go SDK\u003c/h2\u003e\n\n\u003c!-- x-hide-in-docs-end --\u003e\n\u003c!-- The 'github-badges' class is used in the docs --\u003e\n\u003cp align=\"center\" class=\"github-badges\"\u003e\n  \u003ca href=\"https://github.com/open-feature/spec/releases/tag/v0.7.0\"\u003e\n    \u003cimg alt=\"Specification\" src=\"https://img.shields.io/static/v1?label=specification\u0026message=v0.7.0\u0026color=yellow\u0026style=for-the-badge\" /\u003e\n  \u003c/a\u003e\n  \u003c!-- x-release-please-start-version --\u003e\n  \u003ca href=\"https://github.com/open-feature/go-sdk/releases/tag/v1.17.1\"\u003e\n    \u003cimg alt=\"Release\" src=\"https://img.shields.io/static/v1?label=release\u0026message=v1.17.1\u0026color=blue\u0026style=for-the-badge\" /\u003e\n  \u003c/a\u003e\n  \u003c!-- x-release-please-end --\u003e\n  \u003cbr/\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/open-feature/go-sdk/openfeature\"\u003e\n    \u003cimg alt=\"API Reference\" src=\"https://pkg.go.dev/badge/github.com/open-feature/go-sdk/pkg/openfeature.svg\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/open-feature/go-sdk\"\u003e\n    \u003cimg alt=\"Go Report Card\" src=\"https://goreportcard.com/badge/github.com/open-feature/go-sdk\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/open-feature/go-sdk\"\u003e\n    \u003cimg alt=\"codecov\" src=\"https://codecov.io/gh/open-feature/go-sdk/branch/main/graph/badge.svg?token=FZ17BHNSU5\" /\u003e\n  \u003c/a\u003e\n    \u003ca href=\"https://bestpractices.coreinfrastructure.org/projects/6601\"\u003e\n    \u003cimg alt=\"CII Best Practices\" src=\"https://bestpractices.coreinfrastructure.org/projects/6601/badge\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\u003c!-- x-hide-in-docs-start --\u003e\n\n[OpenFeature](https://openfeature.dev) is an open specification that provides a vendor-agnostic, community-driven API for feature flagging that works with your favorite feature flag management tool.\n\n\u003c!-- x-hide-in-docs-end --\u003e\n## 🚀 Quick start\n\n### Requirements\n\nGo language version: [1.24](https://go.dev/doc/devel/release#go1.24.0)\n\n\u003e [!NOTE]\n\u003e The OpenFeature Go SDK only supports currently maintained Go language versions.\n\n### Install\n\n```shell\ngo get github.com/open-feature/go-sdk\n```\n\n### Usage\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"context\"\n    \"github.com/open-feature/go-sdk/openfeature\"\n)\n\nfunc main() {\n    // Register your feature flag provider\n    openfeature.SetProviderAndWait(openfeature.NoopProvider{})\n    // Create a new client\n    client := openfeature.NewClient(\"app\")\n    // Evaluate your feature flag\n    v2Enabled := client.Boolean(\n        context.TODO(), \"v2_enabled\", true, openfeature.EvaluationContext{},\n    )\n    // Use the returned flag value\n    if v2Enabled {\n        fmt.Println(\"v2 is enabled\")\n    }\n}\n```\n\nTry this example in the [Go Playground](https://go.dev/play/p/fSSK8s42hA2).\n\n### API Reference\n\nSee [here](https://pkg.go.dev/github.com/open-feature/go-sdk/openfeature) for the complete API documentation.\n\n## 🌟 Features\n\n| Status | Features                                                            | Description                                                                                                                                                  |\n| ------ |---------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| ✅      | [Providers](#providers)                                             | Integrate with a commercial, open source, or in-house feature management tool.                                                                               |\n| ✅      | [Targeting](#targeting)                                             | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context).                           |\n| ✅      | [Hooks](#hooks)                                                     | Add functionality to various stages of the flag evaluation life-cycle.                                                                                       |\n| ✅      | [Tracking](#tracking)                                               | Associate user actions with feature flag evaluations.                                                                                                        |\n| ✅      | [Logging](#logging)                                                 | Integrate with popular logging packages.                                                                                                                     |\n| ✅      | [Domains](#domains)                                                 | Logically bind clients with providers.                                                                                                                       |\n| ✅      | [Eventing](#eventing)                                               | React to state changes in the provider or flag management system.                                                                                            |\n| ✅      | [Shutdown](#shutdown)                                               | Gracefully clean up a provider during application shutdown.                                                                                                  |\n| ✅      | [Transaction Context Propagation](#transaction-context-propagation) | Set a specific [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context) for a transaction (e.g. an HTTP request or a thread) |\n| ✅      | [Extending](#extending)                                             | Extend OpenFeature with custom providers and hooks.                                                                                                          |\n\n\u003csub\u003eImplemented: ✅ | In-progress: ⚠️ | Not implemented yet: ❌\u003c/sub\u003e\n\n### Providers\n\n[Providers](https://openfeature.dev/docs/reference/concepts/provider) are an abstraction between a flag management system and the OpenFeature SDK.\nLook [here](https://openfeature.dev/ecosystem?instant_search%5BrefinementList%5D%5Btype%5D%5B0%5D=Provider\u0026instant_search%5BrefinementList%5D%5Btechnology%5D%5B0%5D=Go) for a complete list of available providers.\nIf the provider you're looking for hasn't been created yet, see the [develop a provider](#develop-a-provider) section to learn how to build it yourself.\n\nOnce you've added a provider as a dependency, it can be registered with OpenFeature like this:\n\n```go\nopenfeature.SetProviderAndWait(MyProvider{})\n```\n\nIn some situations, it may be beneficial to register multiple providers in the same application.\nThis is possible using [domains](#domains), which is covered in more details below, or the included [multiprovider](#multi-provider-implementation)\nimplementation.\n\n### Targeting\n\nSometimes, the value of a flag must consider some dynamic criteria about the application or user, such as the user's location, IP, email address, or the server's location.\nIn OpenFeature, we refer to this as [targeting](https://openfeature.dev/specification/glossary#targeting).\nIf the flag management system you're using supports targeting, you can provide the input data using the [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context).\n\n```go\n// set a value to the global context\nopenfeature.SetEvaluationContext(openfeature.NewTargetlessEvaluationContext(\n    map[string]any{\n        \"region\":  \"us-east-1-iah-1a\",\n    },\n))\n\n// set a value to the client context\nclient := openfeature.NewClient(\"my-app\")\nclient.SetEvaluationContext(openfeature.NewTargetlessEvaluationContext(\n    map[string]any{\n        \"version\":  \"1.4.6\",\n    },\n))\n\n// set a value to the invocation context\nevalCtx := openfeature.NewEvaluationContext(\n    \"user-123\",\n    map[string]any{\n        \"company\": \"Initech\",\n    },\n)\nboolValue, err := client.BooleanValue(\"boolFlag\", false, evalCtx)\n```\n\n\n### Hooks\n\n[Hooks](https://openfeature.dev/docs/reference/concepts/hooks) allow for custom logic to be added at well-defined points of the flag evaluation life-cycle\nLook [here](https://openfeature.dev/ecosystem/?instant_search%5BrefinementList%5D%5Btype%5D%5B0%5D=Hook\u0026instant_search%5BrefinementList%5D%5Btechnology%5D%5B0%5D=Go) for a complete list of available hooks.\nIf the hook you're looking for hasn't been created yet, see the [develop a hook](#develop-a-hook) section to learn how to build it yourself.\n\nOnce you've added a hook as a dependency, it can be registered at the global, client, or flag invocation level.\n\n```go\n// add a hook globally, to run on all evaluations\nopenfeature.AddHooks(ExampleGlobalHook{})\n\n// add a hook on this client, to run on all evaluations made by this client\nclient := openfeature.NewClient(\"my-app\")\nclient.AddHooks(ExampleClientHook{})\n\n// add a hook for this evaluation only\nvalue, err := client.BooleanValue(\n    context.TODO(), \"boolFlag\", false, openfeature.EvaluationContext{}, WithHooks(ExampleInvocationHook{}),\n)\n```\n\n### Tracking\n\nThe [tracking API](https://openfeature.dev/specification/sections/tracking/) allows you to use OpenFeature abstractions and objects to associate user actions with feature flag evaluations.\nThis is essential for robust experimentation powered by feature flags.\nFor example, a flag enhancing the appearance of a UI component might drive user engagement to a new feature; to test this hypothesis, telemetry collected by a [hook](#hooks) or [provider](#providers) can be associated with telemetry reported in the client's `track` function.\n\n```go\n// initialize a client\nclient := openfeature.NewClient('my-app')\n\n// trigger tracking event action\nclient.Track(\n    context.TODO(),\n    'visited-promo-page',\n    openfeature.EvaluationContext{},\n    openfeature.NewTrackingEventDetails(99.77).Add(\"currencyCode\", \"USD\"),\n    )\n```\n\nNote that some providers may not support tracking; check the documentation for your provider for more information.\n\n### Logging\n\nNote that in accordance with the OpenFeature specification, the SDK doesn't generally log messages during flag evaluation.\n\n#### Logging Hook\n\nThe GO SDK includes a `LoggingHook`, which logs detailed information at key points during flag evaluation, using [slog](https://pkg.go.dev/log/slog) structured logging API.\nThis hook can be particularly helpful for troubleshooting and debugging; simply attach it at the global, client or invocation level and ensure your log level is set to \"debug\".\n\n##### Usage example\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log/slog\"\n    \"os\"\n\n    \"github.com/open-feature/go-sdk/openfeature\"\n    \"github.com/open-feature/go-sdk/openfeature/hooks\"\n    \"github.com/open-feature/go-sdk/openfeature/memprovider\"\n)\n\nfunc main() {\n    // Register an in-memory provider with no flags\n    openfeature.SetNamedProviderAndWait(\"example\", memprovider.NewInMemoryProvider(map[string]memprovider.InMemoryFlag{}))\n\n    // Configure slog\n    handler := slog.NewJSONHandler(os.Stderr, \u0026slog.HandlerOptions{Level: slog.LevelDebug})\n    logger := slog.New(handler)\n\n    // Register a logging hook globally to run on all evaluations\n    loggingHook := hooks.NewLoggingHook(false, logger)\n    openfeature.AddHooks(loggingHook)\n\n    // Create a new client\n    client := openfeature.NewClient(\"example\")\n\n    // Attempt to evaluate a flag that doesn't exist\n    _ = client.Boolean(context.TODO(), \"not-exist\", true, openfeature.EvaluationContext{})\n}\n```\n\n###### Output\n\n```sh\n{\"time\":\"2025-06-03T10:49:23.100783-04:00\",\"level\":\"DEBUG\",\"msg\":\"Before stage\",\"domain\":\"example\",\"provider_name\":\"InMemoryProvider\",\"flag_key\":\"not-exist\",\"default_value\":true,\"stage\":\"before\"}\n{\"time\":\"2025-06-03T10:49:23.101037-04:00\",\"level\":\"ERROR\",\"msg\":\"Error stage\",\"domain\":\"example\",\"provider_name\":\"InMemoryProvider\",\"flag_key\":\"not-exist\",\"default_value\":true,\"error_message\":\"error code: FLAG_NOT_FOUND: flag for key not-exist not found\",\"stage\":\"error\"}\n```\n\nSee [hooks](#hooks) for more information on configuring hooks.\n\n### Domains\n\nClients can be assigned to a domain. A domain is a logical identifier that can be used to associate clients with a particular provider. If a domain has no associated provider, the default provider is used.\n\n```go\nimport \"github.com/open-feature/go-sdk/openfeature\"\n\n// Registering the default provider\nopenfeature.SetProviderAndWait(NewLocalProvider())\n// Registering a named provider\nopenfeature.SetNamedProvider(\"clientForCache\", NewCachedProvider())\n\n// A Client backed by default provider\nclientWithDefault := openfeature.NewDefaultClient()\n// A Client backed by NewCachedProvider\nclientForCache := openfeature.NewClient(\"clientForCache\")\n```\n\n### Eventing\n\nEvents allow you to react to state changes in the provider or underlying flag management system, such as flag definition changes, provider readiness, or error conditions.\nInitialization events (`PROVIDER_READY` on success, `PROVIDER_ERROR` on failure) are dispatched for every provider.\nSome providers support additional events, such as `PROVIDER_CONFIGURATION_CHANGED`.\n\nPlease refer to the documentation of the provider you're using to see what events are supported.\n\n```go\nimport \"github.com/open-feature/go-sdk/openfeature\"\n\n...\nvar readyHandlerCallback = func(details openfeature.EventDetails) {\n    // callback implementation\n}\n\n// Global event handler\nopenfeature.AddHandler(openfeature.ProviderReady, \u0026readyHandlerCallback)\n\n...\n\nvar providerErrorCallback = func(details openfeature.EventDetails) {\n    // callback implementation\n}\n\nclient := openfeature.NewDefaultClient()\n\n// Client event handler\nclient.AddHandler(openfeature.ProviderError, \u0026providerErrorCallback)\n```\n\n### Shutdown\n\nThe OpenFeature API provides a close function to perform a cleanup of all registered providers.\nThis should only be called when your application is in the process of shutting down.\n\n```go\nimport \"github.com/open-feature/go-sdk/openfeature\"\n\nopenfeature.Shutdown()\n```\n\n\n### Transaction Context Propagation\n\nTransaction context is a container for transaction-specific evaluation context (e.g. user id, user agent, IP).\nTransaction context can be set where specific data is available (e.g. an auth service or request handler), and by using the transaction context propagator, it will automatically be applied to all flag evaluations within a transaction (e.g. a request or thread).\n\n```go\nimport \"github.com/open-feature/go-sdk/openfeature\"\n\n// set the TransactionContext\nctx := openfeature.WithTransactionContext(context.TODO(), openfeature.EvaluationContext{})\n\n// get the TransactionContext from a context\nec := openfeature.TransactionContext(ctx)\n\n// merge an EvaluationContext with the existing TransactionContext, preferring\n// the context that is passed to MergeTransactionContext\ntCtx := openfeature.MergeTransactionContext(ctx, openfeature.EvaluationContext{})\n\n// use TransactionContext in a flag evaluation\nclient.BooleanValue(tCtx, ....)\n```\n\n### Multi-Provider Implementation\n\nIncluded with this SDK is an _experimental_ multi-provider that can be used to query multiple feature flag providers simultaneously.\nMore information can be found in the [multi package's README](openfeature/multi/README.md).\n\n## Extending\n\n### Develop a provider\n\nTo develop a provider, you need to create a new project and include the OpenFeature SDK as a dependency.\nThis can be a new repository or included in [the existing contrib repository](https://github.com/open-feature/go-sdk-contrib) available under the OpenFeature organization.\nYou’ll then need to write the provider by implementing the `FeatureProvider` interface exported by the OpenFeature SDK.\n\n```go\npackage myfeatureprovider\n\nimport (\n  \"context\"\n  \"github.com/open-feature/go-sdk/openfeature\"\n)\n\n// MyFeatureProvider implements the FeatureProvider interface and provides functions for evaluating flags\ntype MyFeatureProvider struct{}\n\n// Required: Methods below implements openfeature.FeatureProvider interface\n// This is the core interface implementation required from a provider\n// Metadata returns the metadata of the provider\nfunc (i MyFeatureProvider) Metadata() openfeature.Metadata {\n  return openfeature.Metadata{\n    Name: \"MyFeatureProvider\",\n  }\n}\n\n// Hooks returns a collection of openfeature.Hook defined by this provider\nfunc (i MyFeatureProvider) Hooks() []openfeature.Hook {\n  // Hooks that should be included with the provider\n  return []openfeature.Hook{}\n}\n// BooleanEvaluation returns a boolean flag\nfunc (i MyFeatureProvider) BooleanEvaluation(ctx context.Context, flag string, defaultValue bool, flatCtx openfeature.FlattenedContext) openfeature.BoolResolutionDetail {\n  // code to evaluate boolean\n}\n\n// StringEvaluation returns a string flag\nfunc (i MyFeatureProvider) StringEvaluation(ctx context.Context, flag string, defaultValue string, flatCtx openfeature.FlattenedContext) openfeature.StringResolutionDetail {\n  // code to evaluate string\n}\n\n// FloatEvaluation returns a float flag\nfunc (i MyFeatureProvider) FloatEvaluation(ctx context.Context, flag string, defaultValue float64, flatCtx openfeature.FlattenedContext) openfeature.FloatResolutionDetail {\n  // code to evaluate float\n}\n\n// IntEvaluation returns an int flag\nfunc (i MyFeatureProvider) IntEvaluation(ctx context.Context, flag string, defaultValue int64, flatCtx openfeature.FlattenedContext) openfeature.IntResolutionDetail {\n  // code to evaluate int\n}\n\n// ObjectEvaluation returns an object flag\nfunc (i MyFeatureProvider) ObjectEvaluation(ctx context.Context, flag string, defaultValue any, flatCtx openfeature.FlattenedContext) openfeature.InterfaceResolutionDetail {\n  // code to evaluate object\n}\n\n// Optional: openfeature.StateHandler implementation\n// Providers can opt-in for initialization \u0026 shutdown behavior by implementing this interface\n\n// Init holds initialization logic of the provider\nfunc (i MyFeatureProvider) Init(evaluationContext openfeature.EvaluationContext) error {\n  // code to initialize your provider\n}\n\n// Shutdown define the shutdown operation of the provider\nfunc (i MyFeatureProvider) Shutdown() {\n  // code to shutdown your provider\n}\n\n// Optional: openfeature.EventHandler implementation.\n// Providers can opt-in for eventing support by implementing this interface\n\n// EventChannel returns the event channel of this provider\nfunc (i MyFeatureProvider) EventChannel() \u003c-chan openfeature.Event {\n  // expose event channel from this provider. SDK listen to this channel and invoke event handlers\n}\n```\n\n\u003e Built a new provider? [Let us know](https://github.com/open-feature/openfeature.dev/issues/new?assignees=\u0026labels=provider\u0026projects=\u0026template=document-provider.yaml\u0026title=%5BProvider%5D%3A+) so we can add it to the docs!\n\n### Develop a hook\n\nTo develop a hook, you need to create a new project and include the OpenFeature SDK as a dependency.\nThis can be a new repository or included in [the existing contrib repository](https://github.com/open-feature/go-sdk-contrib) available under the OpenFeature organization.\nImplement your own hook by conforming to the [Hook interface](./pkg/openfeature/hooks.go).\nTo satisfy the interface, all methods (`Before`/`After`/`Finally`/`Error`) need to be defined.\nTo avoid defining empty functions make use of the `UnimplementedHook` struct (which already implements all the empty functions).\n\n```go\nimport (\n  \"context\"\n  \"github.com/open-feature/go-sdk/openfeature\"\n)\n\ntype MyHook struct {\n  openfeature.UnimplementedHook\n}\n\n// overrides UnimplementedHook's Error function\nfunc (h MyHook) Error(context context.Context, hookContext openfeature.HookContext, err error, hookHints openfeature.HookHints) {\n  // code that runs when there's an error during a flag evaluation\n}\n```\n\n\u003e Built a new hook? [Let us know](https://github.com/open-feature/openfeature.dev/issues/new?assignees=\u0026labels=hook\u0026projects=\u0026template=document-hook.yaml\u0026title=%5BHook%5D%3A+) so we can add it to the docs!\n\n## Testing\n\nThe SDK provides a `NewTestProvider` which allows you to set flags for the scope of a test.\nThe `TestProvider` is thread-safe and can be used in tests that run in parallel.\n\nCall `testProvider.UsingFlags(t, tt.flags)` to set flags for a test, and clean them up with `testProvider.Cleanup()`\n\n```go\nimport (\n  \"github.com/open-feature/go-sdk/openfeature\"\n  \"github.com/open-feature/go-sdk/openfeature/testing\"\n)\n\ntestProvider := NewTestProvider()\nerr := openfeature.SetProviderAndWait(testProvider)\nif err != nil {\n  t.Errorf(\"unable to set provider\")\n}\n\n// configure flags for this test suite\ntests := map[string]struct {\n  flags map[string]memprovider.InMemoryFlag\n  want  bool\n}{\n  \"test when flag is true\": {\n    flags: map[string]memprovider.InMemoryFlag{\n      \"my_flag\": {\n        State:          memprovider.Enabled,\n        DefaultVariant: \"on\",\n        Variants: map[string]any{\n          \"on\": true,\n        },\n      },\n    },\n    want: true,\n  },\n  \"test when flag is false\": {\n    flags: map[string]memprovider.InMemoryFlag{\n      \"my_flag\": {\n        State:          memprovider.Enabled,\n        DefaultVariant: \"off\",\n        Variants: map[string]any{\n          \"off\": false,\n        },\n      },\n    },\n    want: false,\n  },\n}\n\nfor name, tt := range tests {\n  tt := tt\n  name := name\n  t.Run(name, func(t *testing.T) {\n\n    // be sure to clean up your flags\n    defer testProvider.Cleanup()\n    testProvider.UsingFlags(t, tt.flags)\n\n    // your code under test\n    got := functionUnderTest()\n\n    if got != tt.want {\n      t.Fatalf(\"uh oh, value is not as expected: got %v, want %v\", got, tt.want)\n    }\n  })\n}\n```\n\n### Mocks\n\nMocks are also available for testing purposes for all interfaces within the OpenFeature SDK. These are primarily\nintended for internal use for testing the SDK, but have been exported to ease the testing burden for any extensions\nor custom components (e.g. hooks \u0026 providers). These mocks are not include in builds by default. The build tag \n`testtools` must be used to have the mocks included in builds.\n\n\u003c!-- x-hide-in-docs-start --\u003e\n## ⭐️ Support the project\n\n- Give this repo a ⭐️!\n- Follow us on social media:\n  - Twitter: [@openfeature](https://twitter.com/openfeature)\n  - LinkedIn: [OpenFeature](https://www.linkedin.com/company/openfeature/)\n- Join us on [Slack](https://cloud-native.slack.com/archives/C0344AANLA1)\n- For more, check out our [community page](https://openfeature.dev/community/)\n\n## 🤝 Contributing\n\nInterested in contributing? Great, we'd love your help! To get started, take a look at the [CONTRIBUTING](CONTRIBUTING.md) guide.\n\n### Thanks to everyone that has already contributed\n\n\u003ca href=\"https://github.com/open-feature/go-sdk/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=open-feature/go-sdk\" alt=\"Pictures of the folks who have contributed to the project\" /\u003e\n\u003c/a\u003e\n\nMade with [contrib.rocks](https://contrib.rocks).\n\u003c!-- x-hide-in-docs-end --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-feature%2Fgo-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopen-feature%2Fgo-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopen-feature%2Fgo-sdk/lists"}