npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@openfeature/go-feature-flag-provider

v2.1.0

Published

A feature flag provider for [OpenFeature](https://openfeature.dev/) that integrates with [go-feature-flag](https://github.com/thomaspoignant/go-feature-flag), a simple and complete feature flag solution.

Readme

Server-side GO Feature Flag Provider

A feature flag provider for OpenFeature that integrates with go-feature-flag, a simple and complete feature flag solution.

This provider supports both in-process and remote evaluation modes, offering flexibility for different deployment scenarios.

Features 🚀

  • Dual Evaluation Modes: In-process evaluation for performance and remote evaluation for centralized control
  • Real-time Configuration Updates: Automatic polling for flag configuration changes
  • Comprehensive Data Collection: Built-in event tracking and analytics
  • Flexible Context Support: Rich evaluation context with targeting rules
  • Remote Fallback: In-process evaluation falls back to the relay proxy when the local engine cannot answer
  • TypeScript Support: Full TypeScript support with type safety

Specification 📋

This provider targets GO Feature Flag Provider Specification 1.0, and evaluates in-process with WASM evaluation module 0.2.4 (embedding engine modules/core v0.7.2). The pinned module version lives in scripts/copy-latest-wasm.js.

Installation 📦

npm install @openfeature/go-feature-flag-provider

Peer Dependencies

npm install @openfeature/server-sdk

Quick Start 🏃‍♂️

Basic Setup

import { OpenFeature } from '@openfeature/server-sdk';
import { GoFeatureFlagProvider, EvaluationType } from '@openfeature/go-feature-flag-provider';

// Initialize the provider
const provider = new GoFeatureFlagProvider({
  endpoint: 'https://your-relay-proxy.com',
  evaluationType: EvaluationType.Remote,
});

// Register the provider
OpenFeature.setProvider(provider);

// Get a client
const client = OpenFeature.getClient();

// Evaluate a flag
const flagValue = await client.getBooleanValue('my-feature-flag', false, {
  targetingKey: 'user-123',
  email: '[email protected]',
});

In-Process Evaluation

For high-performance scenarios where you want to evaluate flags locally:

import { GoFeatureFlagProvider, EvaluationType } from '@openfeature/go-feature-flag-provider';

const provider = new GoFeatureFlagProvider({
  endpoint: 'https://your-relay-proxy.com',
  evaluationType: EvaluationType.InProcess,
  flagChangePollingIntervalMs: 30000, // Poll every 30 seconds
});

Configuration Options ⚙️

Provider Options

| Option | Type | Default | Description | | ----------------------------- | ------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | endpoint | string | Required | The endpoint of the GO Feature Flag relay-proxy | | evaluationType | EvaluationType | InProcess | Evaluation mode: InProcess or Remote | | timeout | number | 10000 | HTTP request timeout in milliseconds | | flagChangePollingIntervalMs | number | 120000 | Polling interval for configuration changes. Each delay is jittered by ±10% so that a fleet restarted together does not poll in lockstep. Set to 0 or less to disable polling (in-process mode only) | | dataFlushInterval | number | 60000 | Data collection flush interval | | maxPendingEvents | number | 10000 | Maximum pending events before flushing | | disableDataCollection | boolean | false | Disable data collection entirely | | apiKey | string | undefined | API key for authentication | | exporterMetadata | ExporterMetadata | undefined | Custom metadata for events | | fetchImplementation | FetchAPI | undefined | Custom fetch implementation | | headers | Record<string, string> | undefined | Extra headers on every relay-proxy request, in both modes | | dataCollectorBaseURL | string | endpoint | Base URL for the data collector, when served separately from the relay proxy | | evaluationFlagList | string[] | all flags | Restrict the retrieved configuration to these flags (in-process mode only) | | wasmBinaryPath | string | undefined | Custom path to the WASM binary file (in-process mode only). |

Authentication

When apiKey is set, the provider sends it as X-API-Key on every call to the relay proxy — flag configuration, remote evaluation and data collection alike. When it is unset or empty, no authentication header is sent at all.

Use headers for a relay proxy behind an API gateway that needs its own credentials. Those headers are sent on every request in both evaluation modes. Content-Type and If-None-Match are transport details owned by the provider and a value supplied under either name is ignored, whatever its casing.

X-API-Key is ignored there only while apiKey is set — that option is the supported way to authenticate, and it wins. With no apiKey configured you may supply one through headers instead.

new GoFeatureFlagProvider({
  endpoint: 'https://relay.example.com',
  apiKey: 'my-relay-proxy-key',
  headers: { 'X-Api-Gateway-Key': 'my-gateway-secret' },
});

Evaluation Types

InProcess Evaluation

  • Performance: Fastest evaluation — flags are evaluated locally, against the configuration held in memory
  • Network: Minimal network calls, only for configuration polling, data collection, and the fallback below
  • Use Case: High-performance applications, real-time evaluation

Remote Evaluation

  • Performance: Network-dependent evaluation
  • Network: Each evaluation requires a network call, works well with side-cars or in the edge
  • Use Case: Centralized control

Remote Fallback

When in-process evaluation cannot produce a result — the local engine reports a parse or general error — the provider evaluates that single flag against the relay proxy instead of returning an error to the caller, using the same endpoint, credentials and timeout. Flags resolved this way carry gofeatureflag_evaluated_remotely: true in their metadata and are excluded from data collection, so the relay proxy records them once rather than twice.

Provider Events

Both evaluation modes report health through the OpenFeature event emitter, each signalling the condition its mode can reach:

| Mode | Event | When | | ---------- | -------------------------------- | ---------------------------------------------------------------------------------- | | In-process | PROVIDER_CONFIGURATION_CHANGED | A poll returns a configuration whose content differs; names the flags that changed | | In-process | PROVIDER_STALE | Three consecutive polls fail. The last known-good configuration keeps being served | | In-process | PROVIDER_READY | A poll succeeds after the provider went stale | | Remote | PROVIDER_ERROR | The relay proxy could not answer an evaluation. Reported on the first failure | | Remote | PROVIDER_READY | An evaluation succeeds again |

Remote mode holds no configuration of its own, so it emits neither PROVIDER_CONFIGURATION_CHANGED — there is nothing cached to change — nor PROVIDER_STALE, which describes a last known-good snapshot ageing. A relay proxy it cannot reach means it cannot evaluate at all, which is why the first failure is reported immediately rather than after a threshold. Both states are recoverable: evaluations keep reaching the provider and the next success restores PROVIDER_READY.

Advanced Usage 🔧

Custom Context and Targeting

const context = {
  targetingKey: 'user-123',
  email: '[email protected]',
  firstname: 'John',
  lastname: 'Doe',
  anonymous: false,
  professional: true,
  rate: 3.14,
  age: 30,
  company_info: {
    name: 'my_company',
    size: 120,
  },
  labels: ['pro', 'beta'],
};

const flagValue = await client.getBooleanValue('my-feature-flag', false, context);

Data Collection and Analytics

The provider automatically collects evaluation data. You can customize this behavior:

const provider = new GoFeatureFlagProvider({
  endpoint: 'https://your-relay-proxy.com',
  evaluationType: EvaluationType.Remote,
  disableDataCollection: false, // Enable data collection
  dataFlushInterval: 20000, // Flush every 20 seconds
  maxPendingEvents: 5000, // Max 5000 pending events
});

Custom WASM Binary Path

When using in-process evaluation, you can specify a custom path for the WASM binary file. This is useful when the WASM file is bundled in a custom location:

const provider = new GoFeatureFlagProvider({
  endpoint: 'https://your-relay-proxy.com',
  evaluationType: EvaluationType.InProcess,
  wasmBinaryPath: '/path/to/custom/gofeatureflag-evaluation.wasm',
});

Custom Exporter Metadata

Add custom metadata to your evaluation events:

import { ExporterMetadata } from '@openfeature/go-feature-flag-provider';

const metadata = new ExporterMetadata()
  .add('environment', 'production')
  .add('version', '1.0.0')
  .add('region', 'us-east-1');

const provider = new GoFeatureFlagProvider({
  endpoint: 'https://your-relay-proxy.com',
  evaluationType: EvaluationType.Remote,
  exporterMetadata: metadata,
});

The metadata is a flat JSON object: values are a string, a boolean, or a number — integers and floats alike. Anything that would nest it or that JSON cannot render — an object, an array, null, NaN, Infinity — throws InvalidOptionsException from add, rather than reaching the collector as a value it cannot store.

provider and openfeature are reserved: they are always present and a value supplied for either is ignored, so events stay attributable to this SDK and language.

Flag Types Supported 🎯

The provider supports all OpenFeature flag types:

Boolean Flags

const isEnabled = await client.getBooleanValue('feature-flag', false, context);
const details = await client.getBooleanDetails('feature-flag', false, context);

String Flags

const message = await client.getStringValue('welcome-message', 'Hello!', context);
const details = await client.getStringDetails('welcome-message', 'Hello!', context);

Number Flags

const percentage = await client.getNumberValue('discount-percentage', 0, context);
const details = await client.getNumberDetails('discount-percentage', 0, context);

Object Flags

const config = await client.getObjectValue('user-config', {}, context);
const details = await client.getObjectDetails('user-config', {}, context);

Tracking Events 📊

The provider supports custom event tracking:

// Track a custom event
client.track('user_action', context, {
  action: 'button_click',
  page: 'homepage',
  timestamp: Date.now(),
});

Contributing 🤝

We welcome contributions! Please see our contributing guidelines for details.

License 📄

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Support 💬