# Use with OpenFeature

> Code against the vendor-neutral OpenFeature API; Switchbox is one line.

[OpenFeature](https://openfeature.dev) is a vendor-neutral feature flag API: a CNCF
standard your application codes against, with the actual flag vendor plugged in as a
*provider*. Think SLF4J for feature flags. Your call sites say
`getBooleanValue('new_checkout', false)`; which vendor answers is one registered
provider object.

Switchbox ships official providers for **JavaScript/React** (`@switchbox/openfeature`)
and **Python** (`switchbox-openfeature`). They are thin translation layers over the
regular SDKs, with zero evaluation logic of their own. Everything about how Switchbox
works stays the same: configs come from the CDN, rules and rollouts evaluate locally,
changes propagate within one 10 second poll. The payoff is that Switchbox becomes one
constructor line. If you ever want to leave, you swap the provider, not your call
sites. Same if you want to arrive: adopting Switchbox from another OpenFeature vendor
is the same one line.

## JavaScript

```bash
npm install @openfeature/web-sdk switchbox-js @switchbox/openfeature
```

```ts
import { OpenFeature } from '@openfeature/web-sdk';
import { SwitchboxProvider } from '@switchbox/openfeature';

// Who is evaluating: targetingKey becomes the Switchbox user_id
await OpenFeature.setContext({ targetingKey: 'user-42', plan: 'pro' });

// Switchbox is this one line
await OpenFeature.setProviderAndWait(
  new SwitchboxProvider({ sdkKey: 'your-sdk-key' }),
);

const client = OpenFeature.getClient();
if (client.getBooleanValue('new_checkout', false)) {
  showNewCheckout();
}
```

`SwitchboxProvider` accepts every [`switchbox-js` option](/docs/sdk/javascript)
(`cdnBaseUrl`, `pollInterval`, `onError`, ...), or an existing `Switchbox` client if
you already manage one.

## React

Use the official [`@openfeature/react-sdk`](https://www.npmjs.com/package/@openfeature/react-sdk)
on top of the same provider. The provider emits `ConfigurationChanged` when a new
config version lands, so mounted hooks re-render within one poll interval of a
dashboard change:

```tsx
import { OpenFeature, OpenFeatureProvider, useFlag } from '@openfeature/react-sdk';
import { SwitchboxProvider } from '@switchbox/openfeature';

await OpenFeature.setContext({ targetingKey: 'user-42' });
await OpenFeature.setProviderAndWait(new SwitchboxProvider({ sdkKey: 'your-sdk-key' }));

function App() {
  return (
    <OpenFeatureProvider>
      <Checkout />
    </OpenFeatureProvider>
  );
}

function Checkout() {
  const { value: showNew } = useFlag('new_checkout', false);
  return showNew ? <NewCheckout /> : <OldCheckout />;
}
```

## Python

```bash
pip install switchbox-openfeature
```

```python
from openfeature import api
from openfeature.evaluation_context import EvaluationContext
from switchbox_openfeature import SwitchboxProvider

api.set_provider(SwitchboxProvider(sdk_key="your-sdk-key"))
client = api.get_client()

context = EvaluationContext(targeting_key="user-42", attributes={"plan": "pro"})

if client.get_boolean_value("new_checkout", False, context):
    show_new_checkout()
```

`SwitchboxProvider(...)` accepts every [`Switchbox` constructor option](/docs/sdk/python),
or `client=` with an existing client you already manage.

## Context mapping

OpenFeature's evaluation context maps directly onto the Switchbox user context:

| OpenFeature | Switchbox |
|---|---|
| `targetingKey` / `targeting_key` | `user_id`, the identity used for deterministic rollout bucketing |
| every other attribute | a targeting attribute, passed through as-is |

So `{ targetingKey: 'user-42', plan: 'pro' }` evaluates exactly like
`{ user_id: 'user-42', plan: 'pro' }` does in the regular SDKs, against the same
[rules](/docs/concepts/targeting) and [rollouts](/docs/concepts/rollouts).

Because evaluation is local, changing the context costs zero network. The web
provider re-evaluates the cached config in memory; vendors that evaluate server-side
make a network round trip on every context change.

## Error behavior

Both providers map onto OpenFeature's standard error codes, and OpenFeature always
answers with your code default when something is off. No guessed values:

- Flag missing from the config: `FLAG_NOT_FOUND`
- Evaluated value has a different type than the call requested: `TYPE_MISMATCH`
- CDN unreachable at startup: the provider reports the ERROR state and every
  evaluation serves the code default, the same fail-safe posture as the SDKs
  themselves

## Scope, honestly

Providers exist for the SDKs Switchbox has: **JavaScript/React (browser)** and
**Python (server)**. OpenFeature support does not add languages beyond those. If you
need Go or Java today, Switchbox is not there yet.

## Next

- [JavaScript SDK](/docs/sdk/javascript) and [Python SDK](/docs/sdk/python), the
  clients the providers wrap.
- [How it works](/docs/concepts/how-it-works), the CDN read path the providers
  inherit.
