> ## Documentation Index
> Fetch the complete documentation index at: https://launchdarkly.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenFeature provider for Cloudflare SDK

<View title="Developer" />

<View title="Federal docs" />

<View title="EU docs" />

This topic documents how to get started with the LaunchDarkly OpenFeature provider for the Cloudflare SDK.

<Note>
  **Provider quick links**

  The LaunchDarkly OpenFeature providers are open source. In addition to this reference guide, we provide source, API reference documentation, and a sample application:

  <table>
    <thead>
      <tr>
        <th>Resource</th>
        <th>Location</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td>OpenFeature Provider API documentation</td>
        <td>[Provider API docs](https://launchdarkly.github.io/js-core/packages/sdk/openfeature-cloudflare-server/docs/)</td>
      </tr>

      <tr>
        <td>GitHub repository</td>
        <td>[openfeature-cloudflare-server](https://github.com/launchdarkly/js-core/tree/main/packages/sdk/openfeature-cloudflare-server)</td>
      </tr>

      <tr>
        <td>Sample application</td>
        <td>[Sample OpenFeature Cloudflare provider application](https://github.com/launchdarkly/js-core/tree/main/packages/sdk/openfeature-cloudflare-server/examples/getting-started)</td>
      </tr>

      <tr>
        <td>Published module</td>
        <td>[npm](https://www.npmjs.com/package/@launchdarkly/openfeature-cloudflare-server)</td>
      </tr>
    </tbody>
  </table>
</Note>

## Get started

The LaunchDarkly OpenFeature provider for the Cloudflare SDK is intended for use in multi-user Cloudflare Workers. It follows the server-side LaunchDarkly model for multi-user contexts. It is not intended for use in desktop or embedded systems applications.

The provider wraps the [Cloudflare SDK](/docs/sdk/edge/cloudflare), which reads flag data from a Cloudflare KV namespace that LaunchDarkly keeps up to date. Before you begin, configure the [Cloudflare integration](/docs/integrations/cloudflare) for your project.

Follow these instructions to start using the LaunchDarkly OpenFeature provider for the Cloudflare SDK in your Cloudflare Worker.

### Version compatibility

The LaunchDarkly OpenFeature provider for the Cloudflare SDK is compatible with the [OpenFeature Node.js SDK v1.x](https://openfeature.dev/docs/reference/technologies/server/javascript), version 1.16.0 and later.

The provider requires version 2.7.0 or later of the [Cloudflare SDK](/docs/sdk/edge/cloudflare).

## Install the provider

First, install the LaunchDarkly and OpenFeature packages:

<CodeGroup>
  ```bash title="Shell" lines wrap theme={null}
  npm install @openfeature/server-sdk
  npm install @launchdarkly/cloudflare-server-sdk
  npm install @launchdarkly/openfeature-cloudflare-server
  ```
</CodeGroup>

Then turn on the Node.js compatibility flag in your `wrangler.toml`. This allows the underlying Cloudflare SDK to use `node:events`:

<CodeGroup>
  ```toml title="wrangler.toml" lines wrap theme={null}
  compatibility_flags = [ "nodejs_compat" ]
  ```
</CodeGroup>

Next, import the OpenFeature and LaunchDarkly namespaces in your application code:

<CodeGroup>
  ```js title="LaunchDarkly Cloudflare provider" lines wrap theme={null}
  import { OpenFeature } from '@openfeature/server-sdk';
  import { LaunchDarklyProvider } from '@launchdarkly/openfeature-cloudflare-server';
  ```
</CodeGroup>

## Initialize the provider

After you install and import the provider, create an instance of [`LaunchDarklyProvider`](https://launchdarkly.github.io/js-core/packages/sdk/openfeature-cloudflare-server/docs/classes/LaunchDarklyProvider.html) and register it with OpenFeature. Specify your client-side ID and your Cloudflare KV namespace binding here. In this example, the binding is `env.LD_KV`. The provider only uses the client-side ID to read flag data for a particular environment from the KV namespace. It does not connect to LaunchDarkly servers.

Here's how:

<CodeGroup>
  ```js title="JavaScript" lines wrap theme={null}
  const provider = new LaunchDarklyProvider('example-client-side-id', env.LD_KV, { sendEvents: true });
  await OpenFeature.setProviderAndWait(provider);

  const client = OpenFeature.getClient();
  ```
</CodeGroup>

<Danger>
  **Initialize the provider once per isolate**

  The KV namespace binding is only available inside your Worker's `fetch` handler, but `OpenFeature.setProviderAndWait` registers the provider on a registry that every concurrent request in the Workers isolate shares. Do not run this initialization on every request. Instead, guard it so it runs once per isolate, and reuse the provider for every subsequent request. To learn more, read [Usage](https://github.com/launchdarkly/js-core/tree/main/packages/sdk/openfeature-cloudflare-server#usage) in the provider GitHub repository, which includes a complete example of this pattern.
</Danger>

<Note>
  **The Cloudflare provider uses a client-side ID**

  The LaunchDarkly Cloudflare provider uses a client-side ID. Client-side IDs are specific to each project and environment. They are not secret, and you can include them in code. Do not embed a server-side SDK key into an edge application. Client-side IDs are available on the **SDK keys** page under **Settings**. To learn more about key types, read [Keys](/docs/sdk/concepts/client-side-server-side#keys-and-credentials).
</Note>

<Note>
  **This provider does not emit OpenFeature events**

  The Cloudflare SDK reads flag data from your KV namespace on each evaluation and does not maintain a connection to LaunchDarkly. As a result, the provider does not emit the OpenFeature `ConfigurationChanged`, `Error`, or `Stale` events. Because each request reads the latest flag data from the KV namespace, you do not need a change notification to receive up-to-date flag values. Re-evaluate the flag on the next request instead.
</Note>

## Construct a context

A [context](/docs/home/getting-started/vocabulary#context) is a generalized way of referring to the people, services, machines, or other resources that encounter feature flags in your product. The OpenFeature specification calls these [evaluation contexts](https://openfeature.dev/docs/reference/concepts/evaluation-context).

In the LaunchDarkly provider:

* Contexts always have a particular [context kind](/docs/home/getting-started/vocabulary#context-kind). If you do not specify a kind, the provider treats the context as having a "user" kind. To specify a different kind, including a multi-context, you must include a `kind` attribute.
* Contexts must have a targeting key. This is optional in the OpenFeature specification, but LaunchDarkly requires a key for evaluation. You can specify this using `targetingKey`, as in the OpenFeature specification, or `key`, which is the typical LaunchDarkly identifier for the targeting key.

Here are examples of a context:

<CodeGroup>
  ```js title="Example user context" lines wrap theme={null}
  const context = {
  targetingKey: "example-user-key", // Could also use "key" instead of "targetingKey".
  };
  ```

  ```js title="Example organization context" lines wrap theme={null}
  const context = {
  kind: "organization",
  targetingKey: "example-user-key" // Could also use "key" instead of "targetingKey".
  };
  ```
</CodeGroup>

For additional examples, read [OpenFeature specific considerations](https://github.com/launchdarkly/js-core/tree/main/packages/sdk/openfeature-cloudflare-server#openfeature-specific-considerations) in the provider GitHub repository.

## Evaluate a context

To evaluate feature flags for a context, use the OpenFeature [Evaluation API](https://openfeature.dev/docs/reference/concepts/evaluation-api). For example:

<CodeGroup>
  ```js title="Evaluate a context" lines wrap theme={null}
  const flagValue = await client.getBooleanValue("example-flag-key", false, context);
  ```
</CodeGroup>

## Track metrics

To associate metrics with actions customers take in your application, use the OpenFeature [Tracking API](https://openfeature.dev/docs/reference/concepts/tracking).

The Cloudflare SDK does not send events unless you enable them. To enable events, pass `{ sendEvents: true }` as the third argument when you construct the `LaunchDarklyProvider`. Then, flush events inside `ctx.waitUntil` so they finish sending after the Worker returns its response. Because flushing only sends the events queued so far, it is safe to call on every request.

Here is an example:

<CodeGroup>
  ```js title="Track a customer action" lines wrap theme={null}
  client.track('example-event-key', context, { "optionalCustomData": "optionalCustomValue"});

  ctx.waitUntil(provider.getClient().flush());
  ```
</CodeGroup>

To learn more, read [`track`](https://launchdarkly.github.io/js-core/packages/sdk/openfeature-cloudflare-server/docs/classes/LaunchDarklyProvider.html#track).

## Access the LaunchDarkly client

You may need access to the `LDClient` from within the [Cloudflare SDK](/docs/sdk/edge/cloudflare) if you are working on use cases not supported by OpenFeature, such as [flushing events](/docs/sdk/features/flush).

To access the `LDClient`, use `getClient()`:

<CodeGroup>
  ```js title="JavaScript" lines wrap theme={null}
  const ldClient = provider.getClient();
  ```
</CodeGroup>
