Skip to content

Running Experiments with the SDK

GrowthBook gives you two ways to run an A/B experiment:

  1. Feature-flag experiments — you create a Feature in the GrowthBook UI, attach an Experiment rule, and read the variation with gb.getFeatureValue(). The assignment logic lives in GrowthBook.
  2. Inline experiments with gb.run() — you define the entire experiment in your code and pass it to the SDK. No feature rule needed in the UI.

gb.run() is useful when you want to experiment on something that does not map cleanly to a feature flag, or when you are prototyping quickly and do not need a full GrowthBook UI setup.

gb.run() returns a result object with three key properties:

PropertyTypeDescription
result.valuestring / number / booleanThe variation value assigned to the current user
result.inExperimentbooleantrue if the user was successfully assigned to a variation bucket
result.variationIdnumberThe 0-based index of the assigned variation

When result.inExperiment is false, the user fell outside the experiment (e.g. traffic coverage is less than 100 %, or the experiment is stopped). In that case result.value is always the first element in the variations array — your safe default.

The snippet below initialises the SDK and calls gb.run() to assign a user to a button-colour variation:

import { GrowthBook } from '@growthbook/growthbook';

const gb = new GrowthBook({
  apiHost: 'https://cdn.growthbook.io',
  clientKey: 'sdk-YOUR_KEY',
});

await gb.init({ timeout: 2000 });

const result = gb.run({
  key: 'button-color-test',
  variations: ['blue', 'green'],
});

if (result.inExperiment) {
  console.log('Variation:', result.value);
  // result.value is 'blue' or 'green'
} else {
  // User is not in the experiment — use default
  console.log('Not in experiment');
}
OptionBenefitCost
Feature-flag experimentTies logic to existing code, more flexibleRequires a code change to wire up the experiment
Visual editor experimentNo code changes neededLimited to UI changes only
  • Calling getFeatureValue without a stable user attribute, so assignment is not stable across sessions
  • Not tracking the exposure event, leaving the analysis with no data
  • Mixing multiple SDK versions’ implementation patterns in the same codebase, causing inconsistent behavior

💡 Real-world example

Engineering teams generally wire experiments into an existing feature flag rather than creating a separate experiment, to reduce the number of code paths they have to maintain.

What does gb.run() return?
What is the main difference between gb.run() and a feature-flag experiment?
What does result.inExperiment being false mean?