Awesome Go

go-feature-flag

CategoryServer Applications
SubcategoryServer Applications
Stars2,120

A simple, complete and lightweight self-hosted feature flag solution 100% Open Source

About go-feature-flag

This large README is shown as a plain-text preview. Read the full README at the source

<p align="center">
  <a href="https://gofeatureflag.org" target="_blank"><img width="400" src="gofeatureflag.svg" alt="go-feature-flag logo" /></a>
  <!-- <a href="https://gofeatureflag.org" target="_blank"><img src="website/static/img/logo/logo_footer.png?raw=true" alt="go-feature-flag logo" /></a> -->
</p>

# 🎛️ GO Feature Flag

<p align="center">
    <a href="https://github.com/thomaspoignant/go-feature-flag/actions/workflows/ci.yml"><img src="https://github.com/thomaspoignant/go-feature-flag/actions/workflows/ci.yml/badge.svg" alt="Build Status" /></a>
    <a href="https://scorecard.dev/viewer/?uri=github.com/thomaspoignant/go-feature-flag"><img src="https://api.scorecard.dev/projects/github.com/thomaspoignant/go-feature-flag/badge"/></a>
    <a href="https://codecov.io/gh/thomaspoignant/go-feature-flag"><img src="https://codecov.io/gh/thomaspoignant/go-feature-flag/branch/main/graph/badge.svg?token=T59ACQWW1H"/></a>
    <a href="https://sonarcloud.io/dashboard?id=thomaspoignant_go-feature-flag"><img src="https://sonarcloud.io/api/project_badges/measure?project=thomaspoignant_go-feature-flag&metric=alert_status" alt="Sonarcloud Status" /></a>
    <a href="https://github.com/thomaspoignant/go-feature-flag/releases"><img src="https://img.shields.io/github/v/release/thomaspoignant/go-feature-flag?filter=v*" alt="Release version" /></a>
    <a href="https://goreportcard.com/report/github.com/thomaspoignant/go-feature-flag"><img src="https://goreportcard.com/badge/github.com/thomaspoignant/go-feature-flag" alt="Build Status" /></a>
    <a href="https://github.com/thomaspoignant/go-feature-flag/blob/main/LICENSE"><img src="https://img.shields.io/github/license/thomaspoignant/go-feature-flag" alt="License"/></a>
    <br/>
    <a href="https://www.bestpractices.dev/projects/6290"><img src="https://www.bestpractices.dev/projects/6290/badge"></a>
    <a href="https://pkg.go.dev/github.com/thomaspoignant/go-feature-flag"><img src="https://godoc.org/github.com/thomaspoignant/go-feature-flag?status.svg" alt="GoDoc" /></a>
    <img src="https://img.shields.io/github/go-mod/go-version/thomaspoignant/go-feature-flag?logo=go%20version" alt="Go version"/>
    <a href="https://github.com/avelino/awesome-go/#server-applications"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Go"></a>
    <a href="https://gofeatureflag.org/slack"><img src="https://img.shields.io/badge/join-us%20on%20slack-gray.svg?longCache=true&logo=slack&colorB=green" alt="Join us on slack"></a>
    <a href="https://github.com/sponsors/thomaspoignant"><img src="https://img.shields.io/github/sponsors/thomaspoignant?logo=GitHub%20Sponsors" alt="Sponsors"></a>
    <br />
    <a href="https://gofeatureflag.org">GO Feature Flag is a simple, complete and lightweight self-hosted cloud native feature flag solution 100% Open Source. 🎛️</a>
</p>

> :pray: If you are using **GO Feature Flag** please consider to add yourself in the [adopters](./ADOPTERS.md) list.  
> This simple act significantly boosts the project's visibility and credibility, making a substantial contribution to its advancement.
> 
> If you want to support me and GO Feature Flag, you can also [become a sponsor](https://github.com/sponsors/thomaspoignant).

## Table of Contents

- [🎛️ GO Feature Flag](#️-go-feature-flag)
  - [Table of Contents](#table-of-contents)
  - [What is GO Feature Flag?](#what-is-go-feature-flag)
  - [What can I do with GO Feature Flag?](#what-can-i-do-with-go-feature-flag)
  - [Part of the OpenFeature Ecosystem](#part-of-the-openfeature-ecosystem)
  - [Getting started](#getting-started)
    - [Create a feature flag configuration](#create-a-feature-flag-configuration)
    - [Create a relay proxy configuration file](#create-a-relay-proxy-configuration-file)
    - [Install the relay proxy](#install-the-relay-proxy)
    - [Use Open Feature SDK](#use-open-feature-sdk)
      - [Install dependencies](#install-dependencies)
      - [Init your Open Feature client](#init-your-open-feature-client)
      - [Evaluate your flag](#evaluate-your-flag)
    - [Installation](#installation)
    - [Create a feature flag configuration](#create-a-feature-flag-configuration-1)
    - [SDK Initialisation](#sdk-initialisation)
    - [Evaluate your flags](#evaluate-your-flags)
  - [Can I use GO Feature Flag with any language?](#can-i-use-go-feature-flag-with-any-language)
  - [Where do I store my flags file?](#where-do-i-store-my-flags-file)
  - [Flags file format](#flags-file-format)
  - [Rule format](#rule-format)
    - [Examples](#examples)
  - [Evaluation Context](#evaluation-context)
  - [Custom bucketing](#custom-bucketing)
  - [Variations](#variations)
    - [Example](#example)
  - [Rollout](#rollout)
    - [Complex rollout strategy available](#complex-rollout-strategy-available)
  - [Notifiers](#notifiers)
  - [Export data](#export-data)
  - [Cli](#cli)
- [How can I contribute?](#how-can-i-contribute)
  - [Contributors](#contributors)
  - [Sponsors](#sponsors)
  - [Adopters](#adopters)

## What is GO Feature Flag?

GO Feature Flag is a lightweight and open-source solution that provides a simple and complete feature flag implementation.

The solution has been built to facilitate the usage of feature flags in your code with the easiest setup possible.

Originally, **GO Feature Flag** was designed as a solution exclusively for the `GO` language. With the new standardization of feature flags by the [Openfeature](https://openfeature.dev/) project, the solution is now available for multiple languages _([list of supported languages](https://gofeatureflag.org/docs/sdk))_ through a simple API server called the relay proxy, which can be hosted.

> [!TIP]
> If you are not familiar with feature flags, I've written an [article](https://medium.com/better-programming/feature-flags-and-how-to-iterate-quickly-7e3371b9986) which explains why feature flags can fasten your iteration cycle.

## What can I do with GO Feature Flag?

- Use the feature flag standard [OpenFeature](https://openfeature.dev) in your favorite language _([see list](#can-i-use-go-feature-flag-with-any-language))_.
- Storing your configuration flags file on various locations (`HTTP`, `S3`, `Kubernetes`, [_see full list_](https://gofeatureflag.org/docs/configure_flag/store_your_flags)).
- Configuring your flags in various [format](https://gofeatureflag.org/docs/configure_flag/flag_format) (`JSON`, `TOML` and `YAML`).
- Adding complex [rules](https://gofeatureflag.org/docs/configure_flag/target-with-flags) to target your users.
- Use a complex rollout strategy for your flags :
  - [Run A/B testing experimentation](https://gofeatureflag.org/docs/configure_flag/rollout-strategies/experimentation).
  - [Progressively rollout a feature](https://gofeatureflag.org/docs/configure_flag/rollout-strategies/progressive).
  - [Schedule your flag updates](https://gofeatureflag.org/docs/configure_flag/rollout-strategies/scheduled).
- Exporting your flags usage data to various destinations such as _(`S3`, `Google cloud storage`, `file`, `Kafka`, see the [_full list_](https://gofeatureflag.org/docs/integrations/export-evaluation-data))_.
- Getting notified when a flag has been changed _(`webhook` and `slack`)_.
- Support your full stack, from the backend to the frontend including your mobile apps.

https://github.com/user-attachments/assets/56e1a2a2-996f-4db8-9c93-28c057e4ed5a

_The code of this demo is available in [`examples/demo`](examples/demo) repository_.

## Part of the OpenFeature Ecosystem

<p align="center">
  <img src="https://raw.githubusercontent.com/thomaspoignant/go-feature-flag/cab0bbc294e77a0a0afff64fd499ff691bb0b792/website/static/img/features/openfeature.svg" width="340" />
</p>

At GO Feature Flag, we believe in the power of open standards and, the importance of vendor neutrality. That's why we've chosen to rely on Open Feature for our SDKs.

By adopting GO Feature Flag you embrace the OpenFeature standard and you get all the benefits of the ecosystem.

- Open-Source standard SDKs
- No Vendor Lock-In
- OpenFeature community based support for SDKs

## Getting started

> [!IMPORTANT]
> Before starting to use **GO Feature Flag** you should decide
> if you want to use Open Feature SDKs or if you want to use GO Feature Flag as a GO Module.
> 
> We recommend using the relay-proxy for a central flag management and evaluation solution,
> it enables the multi-languages support, and it integrates seamlessly with the Open Feature SDKs.  
> This is the best way to get full potential of GO Feature Flag.
> 
> If your project is exclusively in GO, the GO module is an option. It will perform the flag evaluation directly in your GO code.

<a id="using-open-feature"></a>
<details>
<summary><b>Using Open Feature SDKs</b></summary>

### Create a feature flag configuration

Create a new `YAML` file containing your first flag configuration.

```yaml title="flag-config.yaml"
# 20% of the users will use the variation "my-new-feature"
test-flag:
  variations:
    my-new-feature: true
    my-old-feature: false
  defaultRule:
    percentage:
      my-new-feature: 20
      my-old-feature: 80
```

This flag split the usage of this flag, 20% will use the variation `my-new-feature` and 80% the variation `my-old-feature`.

### Create a relay proxy configuration file

Create a new `YAML` file containing the configuration of your relay proxy.

```yaml title="goff-proxy.yaml"
server:
  mode: http
  port: 1031
pollingInterval: 1000
startWithRetrieverError: false
retriever:
  kind: file
  path: /goff/flag-config.yaml
exporter:
  kind: log
```

### Install the relay proxy

And we will run the **relay proxy** locally to make the API available.  
The default port will be `1031`.

```shell
# Launch the container
docker run \
  -p 1031:1031 \
  -v $(pwd)/flag-config.yaml:/goff/flag-config.yaml \
  -v $(pwd)/goff-proxy.yaml:/goff/goff-proxy.yaml \
  gofeatureflag/go-feature-flag:latest

```

_If you don't want to use docker to install the **relay proxy** you can follow other ways to install it in the [documentation](https://gofeatureflag.org/docs/relay-proxy/install_relay_proxy)._

### Use Open Feature SDK

_In this example, we are using the **nodejs SDK**, but you can check other languages [here](https://gofeatureflag.org/docs/sdk)._


#### Install dependencies

```shell
npm i @openfeature/server-sdk @openfeature/go-feature-flag-provider
```

#### Init your Open Feature client

In your app initialization, you have to create a client using the Open Feature SDK and initialize it.

```javascript
const {OpenFeature} = require("@openfeature/server-sdk");
const {GoFeatureFlagProvider} = require("@openfeature/go-feature-flag-provider");


// init Open Feature SDK with GO Feature Flag provider
const goFeatureFlagProvider = new GoFeatureFlagProvider({
  endpoint: 'http://localhost:1031/' // DNS of your instance of relay proxy
});
OpenFeature.setProvider(goFeatureFlagProvider);
const featureFlagClient = OpenFeature.getClient('my-app')
```

#### Evaluate your flag

Now you can evaluate your flags anywhere in your code using this client.

```javascript
// Context of your flag evaluation.
// With GO Feature Flag you MUST provide a targetingKey that is a unique identifier of the user.
const evaluationContext = {
  targetingKey: '1d1b9238-2591-4a47-94cf-d2bc080892f1', // user unique identifier (mandatory)
  firstname: 'john',
  lastname: 'doe',
  email: '[email protected]',
  admin: true, // this field is used in the targeting rule of the flag "flag-only-for-admin"
  // ...
};

const adminFlag = await featureFlagClient.getBooleanValue('flag-only-for-admin', false, evaluationContext);
if (adminFlag) {
  // flag "flag-only-for-admin" is true for the user
  console.log("new feature");
} else {
  // flag "flag-only-for-admin" is false for the user
}
```

</details>

<a id="using-go-module"></a>
<details>
<summary><b>Using the GO Module</b></summary>

### Installation
```bash
go get github.com/thomaspoignant/go-feature-flag
```

### Create a feature flag configuration

Create a new `YAML` file containing your first flag configuration.

```yaml title="flag-config.yaml"
# 20% of the users will use the variation "my-new-feature"
test-flag:
  variations:
    my-new-feature: true
    my-old-feature: false
  defaultRule:
    percentage:
      my-new-feature: 20
      my-old-feature: 80
```

This flag split the usage of this flag, 20% will use the variation `my-new-feature` and 80% the variation `my-old-feature`.

### SDK Initialisation
First, you need to initialize the `ffclient` with the location of your backend file.
```go linenums="1"
err := ffclient.Init(ffclient.Config{
  PollingInterval: 3 * time.Second,
  Retriever:      &fileretriever.Retriever{
    Path: "flag-config.goff.yaml",
  },
})
defer ffclient.Close()
```
*This example will load a file from your local computer and will refresh the flags every 3 seconds (if you omit the
PollingInterval, the default value is 60 seconds).*

> ℹ info  
This is a basic configuration to test locally, in production it is better to use a remote place to store your feature flag configuration file.  
Look at the list of available options in the [**Store your feature flag file** page](https://gofeatureflag.org/docs/integrations/store-flags-configuration#available-retrievers).

### Evaluate your flags
Now you can evaluate your flags anywhere in your code.

```go linenums="1"
user := ffcontext.NewEvaluationContext("user-unique-key")
hasFlag, _ := ffclient.BoolVariation("test-flag", user, false)
if hasFlag {
  // flag "test-flag" is true for the user
} else {
  // flag "test-flag" is false for the user
}
```
The full documentation is available on https://docs.gofeatureflag.org  
You can find more examples in the [examples/](https://github.com/thomaspoignant/go-feature-flag/tree/main/examples) directory.

</details>

## Can I use GO Feature Flag with any language?

Originally GO Feature Flag was built to be a GOlang only library, but it limits the ecosystem too much.  
To be compatible with more languages we have implemented the [GO Feature Flag Relay Proxy](cmd/relayproxy/).
It is a service you can host that provides an API to evaluate your flags, you can call it using HTTP to get your variation.

Since we believe in standardization we are also implementing [OpenFeature](https://github.com/open-feature) providers to interact with this API in the language of your choice.  
_(OpenFeature is still at an early stage, so not all languages are supported and expect some changes in the future)_

For now, we have providers for:

| Language                       | Provider Source                                                                                                               | Version                                                                                                                                                                                                                                                                                                                                   |
|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Go                             | [Go Provider](https://github.com/open-feature/go-sdk-contrib/tree/main/providers/go-feature-flag)                             | [![version](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fproxy.golang.org%2Fgithub.com%2Fopen-feature%2Fgo-sdk-contrib%2Fproviders%2Fgo-feature-flag%2F%40latest&query=%24.Version&label=GO&color=blue&style=flat-square&logo=golang)](https://github.com/open-feature/go-sdk-contrib/tree/main/providers/go-feature-flag) |
| Java / Kotlin (server)         | [Java Provider](https://github.com/open-feature/java-sdk-contrib/tree/main/providers/go-feature-flag)                         | [![version](https://img.shields.io/maven-central/v/dev.openfeature.contrib.providers/go-feature-flag?color=blue&style=flat-square&logo=java)](https://central.sonatype.com/artifact/dev.openfeature.contrib.providers/go-feature-flag)                                                                                                    |
| Android / Kotlin (client)      | [Kotlin Provider](openfeature/providers/kotlin-provider)                                                                      | [![version](https://img.shields.io/maven-central/v/org.gofeatureflag.openfeature/gofeatureflag-kotlin-provider?color=blue&style=flat-square&logo=android)](https://central.sonatype.com/artifact/org.gofeatureflag.openfeature/gofeatureflag-kotlin-provider)                                                                             |                                                                                                    
| Javascript/Typescript (server) | [Server Provider](https://github.com/open-feature/js-sdk-contrib/tree/main/libs/providers/go-feature-flag)                    | [![version](https://img.shields.io/npm/v/%40openfeature%2Fgo-feature-flag-provider?color=blue&style=flat-square&logo=npm)](https://www.npmjs.com/package/@openfeature/go-feature-flag-provider)                                                                                                                                           |
| Javascript/Typescript (client) | [Client Provider](https://github.com/open-feature/js-sdk-contrib/tree/main/libs/providers/go-feature-flag-web)                | [![version](https://img.shields.io/npm/v/%40openfeature%2Fgo-feature-flag-web-provider?color=blue&style=flat-square&logo=npm)](https://www.npmjs.com/package/@openfeature/go-feature-flag-web-provider)                                                                                                                                   |
| Python                         | [Python Provider](openfeature/providers/python-provider)                                                                      | [![version](https://img.shields.io/pypi/v/gofeatureflag-python-provider?color=blue&style=flat-square&logo=pypi)](https://pypi.org/project/gofeatureflag-python-provider/)                                                                                                                                                                 |
| .NET                           | [.NET Provider](https://github.com/open-feature/dotnet-sdk-contrib/tree/main/src/OpenFeature.Providers.GOFeatureFlag) | [![version](https://img.shields.io/nuget/v/OpenFeature.Providers.GOFeatureFlag?color=blue&style=flat-square&logo=nuget)](https://nuget.info/packages/OpenFeature.Providers.GOFeatureFlag)                                                                                                                                                     |
| Ruby                           | [Ruby Provider](https://github.com/open-feature/ruby-sdk-contrib/tree/main/providers/openfeature-go-feature-flag-provider)    | [![version](https://img.shields.io/gem/v/openfeature-go-feature-flag-provider?color=blue&style=flat-square&logo=ruby)](https://rubygems.org/gems/openfeature-go-feature-flag-provider)                                                                                                                                                    |

Frequently Asked Questions

What is go-feature-flag?

go-feature-flag is a Server Applications library for the Go programming language. A simple, complete and lightweight self-hosted feature flag solution 100% Open Source

How many GitHub stars does go-feature-flag have?

go-feature-flag has 2,120 GitHub stars in the directory's latest synchronization.

How do I install go-feature-flag?

Install go-feature-flag with the Go module system using `go get thomaspoignant/go-feature-flag`. Check the repository for the current installation instructions.

What category does go-feature-flag belong to?

go-feature-flag is listed under Server Applications, specifically Server Applications.

← Back to Server Applications