JavaScript SDK

Flipswitch providers for JavaScript/TypeScript — web and server — with real-time SSE support

The Flipswitch JavaScript providers are OpenFeature-compatible with automatic cache invalidation via Server-Sent Events (SSE). Use @flipswitch-io/web-provider for browser apps and @flipswitch-io/server-provider for Node.js.

GitHub: github.com/flipswitch-io/js-sdk

Installation

The SDK is split into two packages depending on your runtime environment:

Web (Browser)

npm install @flipswitch-io/web-provider @openfeature/web-sdk
yarn add @flipswitch-io/web-provider @openfeature/web-sdk
pnpm add @flipswitch-io/web-provider @openfeature/web-sdk

Server (Node.js)

npm install @flipswitch-io/server-provider @openfeature/server-sdk
yarn add @flipswitch-io/server-provider @openfeature/server-sdk
pnpm add @flipswitch-io/server-provider @openfeature/server-sdk

Quick Start

Browser (React, Vue, etc.)

import { FlipswitchWebProvider } from '@flipswitch-io/web-provider';
import { OpenFeature } from '@openfeature/web-sdk';

// Only API key is required
const provider = new FlipswitchWebProvider({
  apiKey: 'YOUR_API_KEY'
});

// Register with OpenFeature
await OpenFeature.setProviderAndWait(provider);

// Get a client and evaluate flags
const client = OpenFeature.getClient();
const darkMode = await client.getBooleanValue('dark-mode', false);
const welcomeMessage = await client.getStringValue('welcome-message', 'Hello!');

Node.js (Server)

import { FlipswitchServerProvider } from '@flipswitch-io/server-provider';
import { OpenFeature } from '@openfeature/server-sdk';

const provider = new FlipswitchServerProvider({
  apiKey: 'YOUR_API_KEY'
});

await OpenFeature.setProviderAndWait(provider);
const client = OpenFeature.getClient();

// Evaluate with context
const context = {
  targetingKey: 'user-123',
  email: 'user@example.com',
  plan: 'premium',
};

const showFeature = await client.getBooleanValue('new-feature', false, context);

Configuration Options

OptionTypeDefaultDescription
apiKeystringrequiredEnvironment API key from dashboard
baseUrlstringhttps://api.flipswitch.ioYour Flipswitch server URL
enableRealtimebooleantrueEnable SSE for real-time flag updates
fetchImplementationtypeof fetchfetchCustom fetch function
persistCachebooleantrue (browser)Persist flag values to localStorage
offlineModebooleantrue (browser)Enable offline support with cached values
enableVisibilityHandlingbooleantrue (browser)Pause SSE when tab is hidden
enablePollingFallbackbooleantrueFall back to polling when SSE fails
pollingIntervalnumber30000Polling interval in ms (fallback mode)
maxSseRetriesnumber5Max SSE retries before polling fallback
// Web provider example (FlipswitchServerProvider accepts the same core options)
const provider = new FlipswitchWebProvider({
  apiKey: 'YOUR_API_KEY',
  baseUrl: 'https://api.flipswitch.io',
  enableRealtime: true,
  enablePollingFallback: true,
  pollingInterval: 30000,
  maxSseRetries: 5,
  // Browser-specific options (web provider only)
  persistCache: true,
  offlineMode: true,
  enableVisibilityHandling: true,
});

Real-Time Updates

When enableRealtime is enabled (default), the SDK maintains an SSE connection to receive instant flag changes:

  1. The SSE client receives a flag-updated or config-updated event
  2. The local cache is immediately invalidated
  3. Next flag evaluation fetches the fresh value
  4. OpenFeature emits a PROVIDER_CONFIGURATION_CHANGED event

Event Handlers

// Works with both FlipswitchWebProvider and FlipswitchServerProvider
const provider = new FlipswitchWebProvider(
  { apiKey: 'YOUR_API_KEY' },
  {
    onFlagChange: (event) => {
      console.log(`Flag changed: ${event.flagKey ?? 'all flags'}`);
      // event.flagKey is null for bulk invalidation
    },
    onConnectionStatusChange: (status) => {
      console.log(`SSE status: ${status}`);
      // 'connecting' | 'connected' | 'disconnected' | 'error'
    },
  }
);

Connection Status

// Check current SSE status
const status = provider.getSseStatus();
// 'connecting' | 'connected' | 'disconnected' | 'error'

// Force reconnect
provider.reconnectSse();

React Integration

import { OpenFeature, OpenFeatureProvider, useFlag } from '@openfeature/react-sdk';
import { FlipswitchWebProvider } from '@flipswitch-io/web-provider';

// Initialize provider (do this once at app startup)
const provider = new FlipswitchWebProvider({
  apiKey: 'YOUR_API_KEY',
});

await OpenFeature.setProviderAndWait(provider);

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

function MyComponent() {
  const { value: darkMode } = useFlag('dark-mode', false);

  return (
    <div className={darkMode ? 'dark' : 'light'}>
      Dark mode is {darkMode ? 'enabled' : 'disabled'}
    </div>
  );
}

The useFlag hook automatically re-renders when flags change via SSE.

Evaluation Context

Pass user attributes for targeting:

const context = {
  targetingKey: 'user-123',      // Required: unique user identifier
  email: 'user@example.com',
  plan: 'premium',
  country: 'SE',
  version: '2.1.0',
};

const showFeature = await client.getBooleanValue('feature', false, context);

Bulk Flag Evaluation

Evaluate all flags at once or get detailed evaluation results:

// Evaluate all flags
const flags = await provider.evaluateAllFlags(context);
for (const flag of flags) {
  console.log(`${flag.key} (${flag.valueType}): ${flag.value}`);
}

// Evaluate a single flag with full details
const flag = await provider.evaluateFlag('dark-mode', context);
if (flag) {
  console.log(`Value: ${flag.value}, Reason: ${flag.reason}, Variant: ${flag.variant}`);
}

Browser Features

Offline Support

When offline mode is enabled, the SDK serves cached values when offline:

const provider = new FlipswitchWebProvider({
  apiKey: 'YOUR_API_KEY',
  offlineMode: true,        // Enable offline support
  persistCache: true,       // Persist to localStorage
});

// Check online status
if (provider.isOnline()) {
  console.log('Online - flags are fresh');
} else {
  console.log('Offline - serving cached values');
}

Visibility API Integration

The SDK automatically pauses SSE when the browser tab is hidden to save resources:

const provider = new FlipswitchWebProvider({
  apiKey: 'YOUR_API_KEY',
  enableVisibilityHandling: true, // default: true in browsers
});
// Connection is paused when tab is hidden, resumes when visible

Polling Fallback

When SSE connection fails repeatedly, the SDK falls back to polling:

const provider = new FlipswitchWebProvider({
  apiKey: 'YOUR_API_KEY',
  enablePollingFallback: true, // default: true
  pollingInterval: 30000,      // Poll every 30 seconds
  maxSseRetries: 5,            // Fall back after 5 failed SSE attempts
});

// Check if polling is active
if (provider.isPollingActive()) {
  console.log('Polling fallback is active');
}

Reconnection Strategy

The SSE client automatically reconnects with exponential backoff:

  • Initial delay: 1 second
  • Maximum delay: 30 seconds
  • Backoff multiplier: 2x

When reconnected, the provider status changes from STALE back to READY.

TypeScript Support

The SDK is written in TypeScript and provides full type definitions:

import type { FlipswitchWebProvider, FlipswitchConfig, SseStatus } from '@flipswitch-io/web-provider';
import type { FlipswitchServerProvider } from '@flipswitch-io/server-provider';

Troubleshooting

SSE connection keeps disconnecting

Check if your server or proxy supports long-lived connections. Some proxies timeout after 30-60 seconds.

Flags not updating in real-time

Verify that enableRealtime is true (default) and check the SSE status:

console.log(provider.getSseStatus());

CORS errors

Ensure your Flipswitch server has CORS configured to allow requests from your domain.

On this page