Bootstrap Feature Flags

Contents

Bootstrapping Feature Flags makes precomputed flag values available as soon as a client-side PostHog SDK initializes. This prevents flicker and enables startup logic, such as redirects, to use flags before the SDK finishes its first /flags request.

This page covers feature flag-specific behavior. See bootstrapping PostHog SDKs for identity, session, persistence, and cross-SDK behavior.

Note: Feature flag bootstrapping is available in the JavaScript web, React Native, iOS, Android, and Flutter SDKs.

Bootstrap flag values

Pass known flag values to bootstrap.featureFlags during SDK initialization:

posthog.init('<ph_project_token>', {
api_host: 'https://us.i.posthog.com',
defaults: '2026-05-30',
bootstrap: {
featureFlags: {
'new-checkout': true,
'checkout-variant': 'test',
},
},
})

You can also seed JSON-serializable payloads with featureFlagPayloads:

Web
posthog.init('<ph_project_token>', {
api_host: 'https://us.i.posthog.com',
defaults: '2026-05-30',
bootstrap: {
featureFlags: {
'checkout-variant': 'test',
},
featureFlagPayloads: {
'checkout-variant': {
buttonText: 'Try the new checkout',
},
},
},
})

Get the correct values from your server

For web apps, evaluate flags on your server as part of the page request, then pass the results to the client:

  1. Get or create the distinct ID the client uses.
  2. Call getAllFlags() for that distinct ID on your server.
  3. Include the flag values and distinct ID in the response that renders the page.
  4. Pass both values to bootstrap when the client initializes PostHog.

Use posthog-node's getAllFlagsAndPayloads() instead when you also need payloads. Use server-side local evaluation to avoid a network request to PostHog while handling the page request.

For mobile apps, get the server-evaluated values before SDK setup and pass them to PostHogBootstrapConfig.

Use the same distinct ID on the server and client

Percentage rollout and variant assignment are deterministic for a distinct ID. If the server evaluates flags with one ID and the client initializes with another, the client can receive a different value when it fetches flags. Keep person properties, group properties, and evaluation contexts consistent too when your flag uses them.

Bootstrap the same ID you used for server-side evaluation:

Web
posthog.init('<ph_project_token>', {
api_host: 'https://us.i.posthog.com',
defaults: '2026-05-30',
bootstrap: {
distinctID: 'distinct_id_used_on_the_server',
isIdentifiedID: true,
featureFlags: serverEvaluatedFlags,
},
})

See bootstrapping an identity for anonymous IDs, identified IDs, and persisted identity reconciliation.

Understand the flag lifecycle

Bootstrapped flags seed the SDK's initial state. They don't permanently override values from PostHog.

  • The SDK serves bootstrapped values immediately.
  • The next complete /flags response replaces the complete set of bootstrapped values. Keys that only exist in the bootstrap configuration are removed.
  • A partial or errored response updates the flags it computed and preserves previous values for the others.
  • Calling reset() clears bootstrapped flags.
  • If you disable automatic feature flag requests, no /flags response replaces the bootstrapped values. Use updateFlags() to supply new values at runtime in SDKs that support it.

Bootstrapping only seeds enabled flags. Use true for a boolean flag or a non-empty string for a multivariate flag. The SDK drops false and empty values. See mobile SDK bootstrapping behavior for persistence and first-launch behavior.

Bootstrap flags in single-page apps

In environments where posthog.init() runs once during a session, such as a single-page app using Next.js instrumentation-client, choose one of these approaches:

  • Server-side pre-evaluation – Evaluate flags before the app renders, then pass the values into the app and add them to bootstrap or use them directly.
  • Client-side pre-evaluation – Evaluate the flag in an earlier page or state than the one where you need it, then store and reuse it.

Both approaches prevent flicker as long as the server and client use the same distinct ID.

Override flags instead of bootstrapping

Use overrides when you need to replace flag values after initialization or keep a value from being replaced by /flags. Bootstrapping is for initial state, not persistent overrides.

posthog.overrideFeatureFlags({ 'new-checkout': true })

Examples

Community questions

Was this page useful?