---
name: flipflag-integration
description: Integrate FlipFlag feature flags into an existing browser, React, Next.js, Vue, Node.js, React Native, Kotlin or Swift application. Use when adding FlipFlag SDKs, configuring cloud or self-host endpoints, implementing safe feature defaults, identity changes or usage metrics. Does not administer flags or replace application authorization.
---

# Integrate FlipFlag

Inspect the application's framework, package manager, existing authentication and deployment environment before editing. Reuse its conventions. Read https://docs.flipflag.ru/llms.txt and the relevant SDK page; inspect installed package types when examples and versions differ. Do not invent API methods, package versions, CLI commands or an MCP integration.

## Establish the integration contract

- Obtain the API origin, project, environment and SDK key from the operator. Use https://api.flipflag.ru for cloud only when the operator confirms it. Self-host uses the customer's origin, for example https://flags.company.example; the SDK appends /v1 itself.
- Use a browser key scoped to the intended environment for browser/mobile code. These keys are visible to end users. Keep server keys in server-only environment variables; never ship them into public bundles, URLs, examples or logs. Server keys are rejected on requests carrying a browser Origin header. A flag is not an authorization boundary.
- Use a stable opaque context.userId. For anonymous users persist a random ID according to the application's privacy policy. Avoid generating a new ID per render or sending email, access tokens or unnecessary personal data as attributes. Replace the context on login, logout and account switching.
- Choose an explicit safe fallback for every flag with the product owner. Separate a flag's enabled configuration from its evaluated boolean value. A returned variant may be false while its reason is fallthrough.

## Implement using the actual SDK

Choose @flipfeatureflag/js, /react, /next, /vue, /node or /react-native as appropriate. Kotlin and Swift use the native integration pages. Check registry availability and the installed version; a commit in the SDK repository does not prove that its package was published.

Browser or a dedicated Node client example:

```ts
import { createClient } from "@flipfeatureflag/js";

const client = createClient({
  url: apiOrigin,
  sdkKey,
  env: "prod",
  context: { userId: stableOpaqueUserId },
});
client.on("error", () => reportFlagServiceUnavailable());
await client.start();
const showNewCheckout = client.isEnabled("new_checkout", false);
const config = client.getVariant("checkout_config", { layout: "classic" }).value;
// On an identity change, replace attributes as well as the ID:
client.updateContext({ userId: nextOpaqueUserId, attributes: { plan: "pro" } });
// On disposal / graceful shutdown:
await client.flushMetrics();
client.stop();
```

Use @flipfeatureflag/node for Node. Never share a mutable user context across concurrent server requests: create a request-owned client with disableRefresh: true and stop it, or implement an explicit request-scoped wrapper. Do not call updateContext on a global client for each incoming request.

For React, prefer FlipFlagProvider and useFlag/useVariant from the React SDK. Render the evaluated value: `useFlag("new_checkout").value === true`. The hook's enabled field describes the presence and activation of the returned flag, not whether its value equals true. Use useUpdateContext for identity changes, keep provider configuration stable and clean up framework subscriptions.

## Handle failures and usage honestly

Current SDKs perform remote evaluation and periodically refresh snapshots; JavaScript defaults to 15 seconds. Reads use the in-memory snapshot. Do not claim streaming, zero polling, local targeting or guaranteed offline persistence. Refresh failures preserve the last successful snapshot; a cold client uses its explicit fallback. Check getStatus().error/ready for diagnostics without blocking unrelated application features. HTTP 402 from an expired on-prem license is a service failure; SDK reads should continue with the cached snapshot or fallback.

Usage events are produced by actual SDK reads, buffered and sent best effort. They can be lost on process termination, network failure or queue limits. UI render behavior can cause multiple reads; do not describe raw evaluations as billed requests, unique users or a financial accounting source. Do not call track in a loop to fabricate metrics.

## Verify before handing over

Run the application's existing type checks and relevant tests. Cover both flag values, missing flag, initial API failure, failure after a successful snapshot, identity replacement and disposal. For SSR test concurrent users independently and check that server keys are absent from public output. Verify browser CORS against the actual configured origin. State the installed version and any untested native build or publication limitation.
