GitHub

Custom Adapters

Integrate any feature flag provider with the Flags SDK using a custom adapter.

Integrate any feature flag provider with the Flags SDK using an adapter. We publish adapters for the most common providers, but it is also possible to write a custom adapter in case we don't list your provider or in case you have an in-house solution for feature flags.

Adapters conceptually replace the decide and origin parts of a flag declaration.

How to write a custom adapter

Creating custom adapters is possible by creating an adapter factory:

example-adapter.ts
import type { Adapter } from 'flags'; import { createClient, EdgeConfigClient } from '@vercel/edge-config';   /**  * A factory function for your adapter  */ export function createExampleAdapter(/* options */) {  // create the client for your provider here, or reuse the one  // passed in through options    return function exampleAdapter<ValueType, EntitiesType>(): Adapter<  ValueType,  EntitiesType  > {  return {  origin(key) {  // link to the flag in the provider's dashboard  return `https://example.com/flags/${key}`;  },  async decide({ key }): Promise<ValueType> {  // use the SDK instance created earlier to evaluate flags here  return false as ValueType;  },  };  }; }

This allows passing the provider in the flag declaration.

flags.tsx
import { flag } from 'flags/next'; import { createExampleAdapter } from './example-adapter';   // create an instance of the adapter const exampleAdapter = createExampleAdapter();   export const exampleFlag = flag({  key: 'example-flag',  // use the adapter for many feature flags  adapter: exampleAdapter(), });

Example

Below is an example of an Flags SDK adapter reading Edge Config.

Exposing default adapters

In the example above, as a user of the adapter, we first needed to create an instance of the adapter. It is possible to simplify usage further by exposing a default adapter.

Usage with a default adapter, where we can import a fully configured exampleAdapter.

flags.tsx
import { flag } from 'flags/next'; import { exampleAdapter } from './example-adapter';   export const exampleFlag = flag({  key: 'example-flag',  // use the adapter for many feature flags  adapter: exampleAdapter(), });

Many @flags-sdk/* adapters will implement this pattern. The default adapter will get created lazily on first usage, and can initialize itself based on known environment variables.

example-adapter.ts
// extend the adapter definition to expose a default adapter let defaultEdgeConfigAdapter:  | ReturnType<typeof createEdgeConfigAdapter>  | undefined;   /**  * A default Vercel adapter for Edge Config  *  */ export function edgeConfigAdapter<ValueType, EntitiesType>(): Adapter<  ValueType,  EntitiesType > {  // Initialized lazily to avoid warning when it is not actually used and env vars are missing.  if (!defaultEdgeConfigAdapter) {  if (!process.env.EDGE_CONFIG) {  throw new Error('Edge Config Adapter: Missing EDGE_CONFIG env var');  }    defaultEdgeConfigAdapter = createEdgeConfigAdapter(process.env.EDGE_CONFIG);  }    return defaultEdgeConfigAdapter<ValueType, EntitiesType>(); }