GitHub

GrowthBook

The GrowthBook adapter integrates GrowthBook with the Flags SDK, enabling feature flagging, experimentation, and configuration management in your application. This adapter provides a seamless way to evaluate feature flags and experiments, with support for server-side, client-side, and Edge Config bootstrapping.

GrowthBook is an open-source feature flagging and experimentation platform that helps you safely roll out features, run A/B tests, and manage configuration at scale.

Deploy the GrowthBook template

Installation

Install the GrowthBook adapter package:

npm install @flags-sdk/growthbook

Adapter Usage

Import the Default Adapter

A default adapter is available for use, assuming the appropriate environment variables are set.

import { growthbookAdapter } from '@flags-sdk/growthbook';

Environment Variables

The default adapter considers the following environment variables:

Environment VariableDescription
GROWTHBOOK_CLIENT_KEYRequired. GrowthBook SDK key
GROWTHBOOK_API_HOSTOptional. Override the GrowthBook API endpoint
GROWTHBOOK_APP_ORIGINOptional. Override the GrowthBook app URL
GROWTHBOOK_EDGE_CONNECTION_STRINGOptional. Edge Config connection string
GROWTHBOOK_EDGE_CONFIG_ITEM_KEYOptional. Edge Config item key (Defaults to your client key)
EXPERIMENTATION_CONFIGOptional. Used when installed through Vercel Marketplace (replaces GROWTHBOOK_EDGE_CONNECTION_STRING)

Create a Custom Adapter

You can provide custom configuration by using createGrowthBookAdapter:

import { createGrowthBookAdapter } from '@flags-sdk/growthbook';
 
const myGrowthBookAdapter = createGrowthBookAdapter({
  clientKey: process.env.GROWTHBOOK_CLIENT_KEY!,
  apiHost: process.env.GROWTHBOOK_API_HOST, // optional
  appOrigin: process.env.GROWTHBOOK_APP_ORIGIN, // optional
  edgeConfig: {
    connectionString: process.env.GROWTHBOOK_EDGE_CONNECTION_STRING!,
    itemKey: process.env.GROWTHBOOK_EDGE_CONFIG_ITEM_KEY, // optional
  },
  trackingCallback: (experiment, result) => {
    // Custom exposure logging
  },
  clientOptions: {}, // GrowthBook ClientOptions (optional)
  initOptions: {},   // GrowthBook InitOptions (optional)
  stickyBucketService: undefined, // Optional
});

User Identification

GrowthBook uses Attributes to evaluate feature flags and experiments.

You should write an identify function providing these Attributes to GrowthBook flags.

import { dedupe, flag } from 'flags/next';
import type { Identify } from 'flags';
import { growthbookAdapter, type Attributes } from '@flags-sdk/growthbook';
 
const identify = dedupe((async ({ headers, cookies }) => {
  return {
    id: cookies.get('user_id')?.value,
    // ...other attributes
  };
}) satisfies Identify<Attributes>);
 
export const myFeatureFlag = flag({
  key: 'my_feature_flag',
  identify,
  adapter: growthbookAdapter.feature<boolean>(),
});

Dedupe is used above to ensure that the Attributes are computed once per request.

Adapter Methods and Properties

feature<T>()

This method implements the Adapter interface for a GrowthBook feature. Typically flag definitions are applied in a single file (e.g. flags.ts).

export const myFlag = flag({
  key: 'my_flag',
  adapter: growthbookAdapter.feature<string>(),
  defaultValue: false,
  identify,
});
OptionDefaultDescription
exposureLoggingtrueEnable/disable exposure logging.

If your flag returns a type other than boolean, you can provide a type argument to the feature method.

initialize

Initializes the GrowthBook SDK. This is done on-demand when a growthbook flag is evaluated, and is not required to be called manually.

const growthbookClient = await growthbookAdapter.initialize();

setTrackingCallback

Set a back-end callback to handle experiment exposures. This allows you to log exposures to your analytics platform. Typically this is done in the same file where your flags are defined (e.g. flags.ts).

import { growthbookAdapter } from '@flags-sdk/growthbook';
import { after } from 'next/server';
 
growthbookAdapter.setTrackingCallback((experiment, result) => {
  // Safely fire and forget async calls (Next.js)
  after(async () => {
    console.log('Viewed Experiment', {
      experimentId: experiment.key,
      variationId: result.key,
    });
  });
});

Front-end experiment tracking is also supported, although it requires additional manual setup. See the GrowthBook docs for more information.

setStickyBucketService

Sticky bucketing ensures users continue to see the same variation when you make changes to a running experiment. GrowthBook's flavor of sticky bucketing has a few additional features:

  1. Bucketing based on either a primary hash attribute (i.e. user id) or a secondary attribute (i.e. anonymous id)
  2. The ability to version-control and purge your users' assigned buckets.

See GrowthBook's documentation on Sticky Bucketing for more details.

import { growthbookAdapter } from '@flags-sdk/growthbook';
import { StickyBucketService } from '@growthbook/growthbook';
 
class MyStickyBucketService extends StickyBucketService {
  // Implement your sticky bucket service
}
 
growthbookAdapter.setStickyBucketService(new MyStickyBucketService());

.growthbook

You may access the underlying GrowthBook instance. Specifically, the GrowthBook Flags SDK adapter wraps a GrowthBookClient instance.

.stickyBucketService

If you have set a sticky bucket service, you may retrieve its instance here.

Edge Config

The adapter can load feature configuration from Vercel Edge Config to lower the latency of feature flag evaluation.

  • Set GROWTHBOOK_EDGE_CONNECTION_STRING (or EXPERIMENTATION_CONFIG if installed through the Vercel Marketplace) in your environment. Optionally set GROWTHBOOK_EDGE_CONFIG_ITEM_KEY to override the default key name (defaults to your client key).
  • Or pass edgeConfig directly to the adapter.

If Edge Config is not set, the adapter will fetch configuration from GrowthBook's API.

Configuring a SDK Webhook

  1. To automatically populate the Edge Config whenever your feature definitions change, create a GrowthBook SDK Webhook on the same SDK Connection that you are using for the Next.js integration.ts

  2. Select "Vercel Edge Config" as the webhook type and fill out the following fields:

  • Vercel Edge Config ID (begins with ecfg_)
  • Team ID (optional)
  • Vercel API Token (see Vercel → Account Settings → Tokens)

Under the hood, the webhook is being configured with the following properties. If you need to change any of these settings for any reason, you can always edit the webhook.

  • Endpoint URL is being set to
    https://api.vercel.com/v1/edge-config/{edge_config_id}/items
  • Method is being set to PATCH
  • An Authorization: Bearer token header is being added with your Vercel API Token
  • The Payload format is being set to Vercel Edge Config

Caveats & Best Practices

  • Initialization: The adapter auto-initializes when a flag is evaluated. To pre-initialize, call initialize() manually.
  • Exposure Logging: By default, exposures are logged when flags are evaluated. You can disable this with exposureLogging: false or provide a custom tracking callback.
  • Sticky Buckets: For advanced experimentation (e.g., Bandits), use a StickyBucketService.
  • Multiple Flags, Same Key: You can use the same GrowthBook feature key with different mapping functions if needed.

Flags Explorer Integration

To expose GrowthBook data to the Flags Explorer, use the getProviderData function in your API route:

import { getProviderData, createFlagsDiscoveryEndpoint } from 'flags/next';
import { getProviderData as getGrowthBookProviderData } from '@flags-sdk/growthbook';
import { mergeProviderData } from 'flags';
import * as flags from '../../../../flags';
 
export const GET = createFlagsDiscoveryEndpoint(async (request) => {
  return mergeProviderData([
    getProviderData(flags),
    getGrowthBookProviderData({
      // Add any required options here
    }),
  ]);
});

More Resources