Docs/SDKs/

JavaScript / TypeScript SDK

Use Flagpool in any JavaScript or TypeScript application

The official JavaScript/TypeScript SDK for Flagpool. Evaluate feature flags locally with zero server round-trips, deterministic rollouts, and real-time updates.

Installation

npm install @flagpool/sdk

Quick Start

import { FlagpoolClient } from '@flagpool/sdk'

const client = new FlagpoolClient({
  projectId: 'your-project-uuid',
  apiKey: 'your-api-key',
  decryptionKey: 'your-decryption-key',
  context: {
    userId: 'user-123',
    email: 'alice@example.com',
    plan: 'pro',
  },
})

await client.init()

// Boolean flag
if (client.isEnabled('new-dashboard')) {
  showNewDashboard()
}

// String, number, or JSON flag
const buttonColor = client.getValue('cta-button-color')

// Clean up when done
client.close()

Configuration

const client = new FlagpoolClient({
  // Required
  projectId: 'your-project-uuid',
  apiKey: 'your-api-key',
  decryptionKey: 'your-decryption-key',

  // Optional
  context: {
    userId: 'user-123',
    email: 'user@example.com',
    plan: 'pro',
  },
  pollingInterval: 30000, // Auto-refresh interval in ms (default: 30000)
  urlOverride: undefined, // Complete URL override (for self-hosted/testing)
  analytics: {
    enabled: true, // Enable evaluation analytics (default: false)
  },
})
OptionTypeRequiredDescription
projectIdstringYesProject UUID from the dashboard
apiKeystringYesEnvironment-specific API key
decryptionKeystringYesFor CDN URL hashing and target list decryption
contextobjectNoUser context for targeting rules
pollingIntervalnumberNoPolling interval in ms (default: 30000)
urlOverridestringNoComplete URL override for self-hosted setups
analyticsobjectNoAnalytics configuration (opt-in)

API Reference

MethodDescription
init()Initialize client and fetch flags (required before evaluation)
isEnabled(key, defaultValue?)Check if a boolean flag is enabled
getValue(key)Get flag value (any type)
getVariation(key)Alias for getValue
getAllFlags()Get all evaluated flag values as an object
updateContext(ctx)Update user context — flags re-evaluate automatically
onChange(callback)Subscribe to flag value changes; returns an unsubscribe function
close()Stop polling and flush analytics

Flag Types

Boolean Flags

if (client.isEnabled('feature-flag')) {
  // Feature is enabled for this user
}

String Flags

Perfect for A/B tests and feature variants:

const variant = client.getValue('button-color')
// 'blue' | 'green' | 'orange'

Number Flags

Great for limits, thresholds, and configurations:

const limit = client.getValue('rate-limit')
// 100 | 1000 | 10000

JSON Flags

For complex configurations:

const config = client.getValue('checkout-config')
// { showCoupons: true, maxItems: 50, paymentMethods: [...] }

Dynamic Context Updates

Update user context on the fly — flags re-evaluate automatically:

// User on free plan
console.log(client.getValue('max-upload-size-mb')) // 10

// User upgrades to pro
client.updateContext({ plan: 'pro' })

// Instantly gets pro limits
console.log(client.getValue('max-upload-size-mb')) // 100

Real-Time Updates

Flags automatically refresh in the background via polling. Listen for changes:

client.onChange((flagKey, newValue) => {
  console.log(`Flag ${flagKey} changed to:`, newValue)

  if (flagKey === 'maintenance-mode' && newValue === true) {
    showMaintenanceBanner()
  }
})

Offline Support

The SDK caches flags locally. If the network is unavailable during initialization, it falls back to cached values from the last successful fetch:

await client.init() // Uses cache if network fails

const feature = client.isEnabled('my-feature') // Always returns a value

Framework Examples

Node.js / Express

import { FlagpoolClient } from '@flagpool/sdk'
import express from 'express'

const app = express()

const flagpool = new FlagpoolClient({
  projectId: process.env.FLAGPOOL_PROJECT_ID!,
  apiKey: process.env.FLAGPOOL_API_KEY!,
  decryptionKey: process.env.FLAGPOOL_DECRYPTION_KEY!,
})

await flagpool.init()

app.get('/api/data', (req, res) => {
  flagpool.updateContext({ userId: req.user.id })

  if (flagpool.isEnabled('new-api-response')) {
    return res.json({ version: 'v2', data: newData })
  }
  return res.json({ version: 'v1', data: legacyData })
})

Next.js (Server-Side)

import { FlagpoolClient } from '@flagpool/sdk'

let client: FlagpoolClient | null = null

export async function getFlags(userId: string) {
  if (!client) {
    client = new FlagpoolClient({
      projectId: process.env.FLAGPOOL_PROJECT_ID!,
      apiKey: process.env.FLAGPOOL_API_KEY!,
      decryptionKey: process.env.FLAGPOOL_DECRYPTION_KEY!,
      context: { userId },
    })
    await client.init()
  }

  return {
    newDashboard: client.isEnabled('new-dashboard'),
    buttonColor: client.getValue('button-color'),
  }
}

For client-side React/Next.js usage, see the React SDK.

Analytics

Track flag evaluation counts. Analytics is opt-in and disabled by default.

const client = new FlagpoolClient({
  // ...required options
  analytics: {
    enabled: true,
    flushInterval: 60000, // Flush interval in ms (min: 30000)
    flushThreshold: 100, // Flush after N evaluations
    sampleRate: 1.0, // Sample rate (0.0–1.0)
  },
})
OptionTypeDefaultDescription
enabledbooleanfalseEnable/disable analytics
flushIntervalnumber60000Flush interval in ms (minimum: 30000)
flushThresholdnumber100Flush after N evaluations
sampleRatenumber1.0Sample rate (0.0–1.0)

Debugging in the Browser

// Inspect state in the browser console
console.log(__FLAGPOOL__.state.analytics)
console.log(__FLAGPOOL__.state.flags)

// Force flush
__FLAGPOOL__.flushAnalytics()

Targeting Operators

OperatorDescriptionExample
eqEqualsplan == "enterprise"
neqNot equalsplan != "free"
inIn listcountry in ["US", "CA"]
ninNot in listcountry not in ["CN", "RU"]
containsString containsemail contains "@company.com"
startsWithString starts withuserId startsWith "admin-"
inTargetListIn target listuserId in beta-testers
notInTargetListNot in target listuserId not in blocked-users

Next Steps

Start Managing Feature Flags Today

Join teams who trust Flagpool to deliver features safely and efficiently.

No credit card required • Cancel anytime