Docs/Guides/

Practical guide / Beta releases

How to use feature flags for beta testing

A step-by-step guide to choosing beta testers, targeting features, and expanding access safely with Flagpool.

To use feature flags for beta testing, put a new feature behind a flag, keep it off for your general audience, and enable it for a selected group of beta testers. Both groups use the same production application, so you can change who gets access without maintaining a separate beta build.

One production applicationA new dashboard, behind a flagbeta-new-dashboard
Flag enabledBeta testers

See the new dashboard and share feedback.

Flag disabledEveryone else

Keep using the current dashboard.

Same deployment. Two experiences. You choose who gets access.

Why use flags for beta testing?

Flags separate deploying code from releasing a feature. Deploy the beta code alongside the existing experience, then use targeting to choose who sees it.

  • Start with a small audience. Invite your team or a handful of customers before opening access more widely.
  • Control each feature separately. A tester can try the new dashboard without also joining an unrelated beta.
  • Change access without a redeploy. Update your audience in Flagpool; your app picks up the updated configuration through the SDK.

Flags control access, not the quality of the release. Still test the feature before deployment, provide a feedback channel, and monitor errors during the beta. Flags also do not replace server-side authorization for protected data or actions.

Set up a beta program in Flagpool

This example releases a new dashboard to an invited group. You'll need a Flagpool project, an environment, and a stable user ID in your application.

1. Create a flag for the beta feature

Create a boolean flag called beta-new-dashboard in the environment your production app uses.

Configure its variations and initial audience:

SettingValue
Variation 0true (new dashboard)
Variation 1false (current dashboard)
Default variation0 (true, for users included in the rollout)
Rollout percentage0% (no general-audience access yet)

With this configuration, users who do not match a targeting rule receive variation 1 (false). In the next steps, you'll give invited testers an explicit rule that returns true.

Keep the beta closed: A targeting rule alone does not exclude everyone else. Keep the general rollout at 0% until you're ready to expand access, and test both a beta user and a non-beta user.

2. Choose your beta testers

In the Flagpool dashboard:

  1. Open Target Lists and create a new list.
  2. Name it beta-testers.
  3. Set its attribute to userId.
  4. Add the user IDs of the people you want to invite.

Use the same IDs your application will pass to the SDK. A list of email addresses will not match a context that only supplies user IDs.

3. Enable the flag for that group

Add this targeting rule to beta-new-dashboard:

AttributeOperatorTarget listReturn
userIdinTargetListbeta-testersVariation 0 (true)

Targeting rules are evaluated before the percentage rollout. A matching beta tester receives true, even with the general rollout at 0%. Everyone else receives false.

If the flag already has other rules, check their priority: the first matching rule wins.

4. Evaluate the flag in your application

Pass the signed-in user's ID in the SDK context, then use the flag to choose between the new and current dashboards.

Target lists need decryption: Configure a crypto adapter before initializing the JavaScript SDK, or pass one to the React provider, so the SDK can decrypt encrypted target lists. Supply the environment's decryption key too. Do not launch the beta until you've confirmed a non-member receives false.

These examples assume you've configured the crypto adapter for your runtime. Replace the project and environment credentials with your own, and obtain user.id from your application's authenticated user.

import { FlagpoolClient } from '@flagpool/sdk'

const client = new FlagpoolClient({
  projectId: 'your-project-uuid',
  apiKey: 'your-environment-api-key',
  decryptionKey: 'your-environment-decryption-key',
  context: { userId: user.id },
  pollingInterval: 30000,
})

await client.init()

function renderDashboard() {
  if (client.isEnabled('beta-new-dashboard', false)) {
    showNewDashboard()
  } else {
    showCurrentDashboard()
  }
}

renderDashboard()

const unsubscribe = client.onChange((flagKey) => {
  if (flagKey === 'beta-new-dashboard') {
    renderDashboard()
  }
})

// On teardown, call unsubscribe() and client.close().
import { Feature, FlagpoolProvider } from '@flagpool/react'

function App({ user, cryptoAdapter }) {
  return (
    <FlagpoolProvider
      projectId="your-project-uuid"
      apiKey="your-environment-api-key"
      decryptionKey="your-environment-decryption-key"
      cryptoAdapter={cryptoAdapter}
      context={{ userId: user.id }}
      pollingInterval={30000}
    >
      <Feature flag="beta-new-dashboard" fallback={<CurrentDashboard />}>
        <NewDashboard />
      </Feature>
    </FlagpoolProvider>
  )
}

Keep the current dashboard as the fallback while the SDK initializes. When the signed-in user changes, update the SDK context too: use client.updateContext() in JavaScript or setContext() from useFlagpool() in React.

5. Check the experience and collect feedback

Before inviting users, verify these three cases:

  • Invited tester: A user ID in beta-testers sees the new dashboard.
  • Non-beta user: A user ID outside the list sees the current dashboard.
  • Removed tester: After the updated configuration reaches the SDK, a removed user sees the current dashboard again.

Give testers a way to report issues, such as an in-app feedback link. Monitor errors and your own product metrics alongside that feedback. Flag-evaluation analytics can show evaluations, but they do not tell you whether users liked the feature or completed a task successfully.

Manage beta testers

Invite or remove users

Add or remove user IDs in the beta-testers target list. Access changes after the updated configuration is published and fetched by the SDK, then reflected in your UI.

The JavaScript example above explicitly polls every 30 seconds and subscribes to flag changes; the React provider updates consumers when values change. Publication, caching, and connectivity can affect when an update arrives, so this is not a guaranteed 30-second deadline.

Let users opt in

If you prefer self-service enrollment, store the user's beta preference in your application and pass it as a context attribute:

client.updateContext({
  userId: user.id,
  betaOptIn: user.betaOptIn,
})

Add a rule that returns variation 0 (true) when betaOptIn eq true. Keep the general rollout at 0% to exclude users who have not opted in.

Choose this approach when anyone may join the beta. For invitation-only access, keep using a controlled target list rather than trusting a client-supplied opt-in attribute.

Expand access and release the feature

Open the beta to more users

When you're ready for broader testing, keep the invited-tester rule and increase the general rollout from 0% to, for example, 5%.

  • Invited testers still receive true through their targeting rule.
  • A deterministic cohort of approximately 5% of the remaining users receives true through the rollout.
  • Everyone else continues to receive false.

Keep variation 0 (true) as the default for users included in the rollout, and pass a stable userId. The cohort is based on the user ID and flag key, so users are not randomly reassigned on every visit.

This opens access beyond your invitation list. If the beta must remain invitation-only, add more people to the list instead of increasing the general rollout.

Read the percentage rollout guide for more detail.

If something goes wrong

Return the beta audience to the current experience by changing the matching beta rule to return false, and set the general rollout to 0%. If you use a separate kill-switch flag, ensure your code checks it before rendering the beta.

Reducing the rollout alone does not disable access for testers whose targeting rule still returns true. Updates also need to reach the SDK before taking effect. See kill-switch patterns.

Graduate from beta

  1. Increase the rollout gradually to 100% while monitoring feedback, errors, and product metrics.
  2. Remove beta-only targeting rules after confirming everyone should receive the released experience.
  3. Deploy code that uses the new dashboard without the flag check.
  4. Once no deployed application version still relies on the flag, archive it and remove any unused target-list references.

Do not archive the flag before removing the flag check: an older application could fall back to the current dashboard when the flag is missing.

Related guides

Start Managing Feature Flags Today

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

No credit card required • Cancel anytime