The documentation is meant for client-side environments. Check out the Node.js docs for server-side environments. JS SDK Resources v1.6.5 sdk-jsnpmTypescript example appGet help on SlackDocumentation Index
Fetch the complete documentation index at: https://growthbook-preview.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Installation
Install with a package manager- npm
- Yarn
- pnpm
- Bun
Quick Usage
Step 1: Configure your app
Step 2: Start Feature Flagging!
There are 2 main methods for evaluating features:isOn and getFeatureValue:
Plugins
GrowthBook comes with a number of built-in plugins that add additional functionality. You can enable these by passing them into the GrowthBook constructor. Plugins require GrowthBook version 1.4.0 or higher, released in Feb 2025.Third Party Tracking
The third-party tracking plugin automatically sends an “Experiment Viewed” event to several popular analytics tracking tools (Segment, Google Analytics, and Google Tag Manager). This plugin requires a browser environment and does not work from Node.js. This plugin does not install any 3rd party libraries, it just sends events to ones that are already installed on your site. Below are all of the supported trackers:segment- Requireswindow.analyticsto be defined.gtag- Requireswindow.gtagto be defined.gtm- Requireswindow.dataLayerto be defined.
Auto-Attributes
The auto-attributes plugin automatically detects and sets common attributes in GrowthBook for the current user. These attributes are available locally for targeting and are not sent to GrowthBook’s servers. This plugin requires a browser environment and does not work from Node.js.Attributes
Here is a list of all attributes that are set by this plugin:id- A random unique identifier for the user, persisted in a cookieurl- The current URL of the pagepath- The current URL path of the pagehost- The current URL host of the pagequery- The current URL query string of the pagepageTitle- The current page titledeviceType- The device type of the user. Either “mobile” or “desktop”browser- The browser name of the user (edge, chrome, firefox, safari, or unknown)utmSource,utmMedium,utmCampaign,utmTerm,utmContent- UTM parameters from the URL (persisted in sessionStorage for subsequent page views)
window.dataLayer) will be added as attributes as well.
You can still specify your own custom attributes in the GrowthBook constructor, and they will be merged with the auto-attributes.
Options
By default the plugin generates a random UUID for the user and stores it in a cookie. You can customize this behavior with the following options.uuidKey- The attribute key to use for the uuid (default isid)uuid- Pass in your own user id instead of having the plugin generate a random one.uuidCookieName- The name of the cookie to use for the generated uuid (default isgb_uuid)uuidAutoPersist- Iffalse, the generated id will NOT be stored in a cookie automatically. Default depends on theuuidoption. Ifuuidis set, the default isfalse. Otherwise, the default istrue.
uuidAutoPersist to false and then later manually trigger the cookie to be saved by calling:
Loading Features and Experiments
In order for the GrowthBook SDK to work, it needs to have feature and experiment definitions from the GrowthBook API. There are a few ways to get this data into the SDK.Built-in Fetching and Caching
If you pass anapiHost and clientKey into the GrowthBook constructor, it will handle the network requests, caching, retry logic, etc. for you automatically. If your feature payload is encrypted, you can also pass in a decryptionKey.
null. If you’re ok with a potential flicker in your application (features going from null to their real value), you can call init without awaiting the result.
If you want to refresh the features at any time (e.g. when a navigation event occurs), you can call gb.refreshFeatures().
Error Handling
In the case of network issues, theinit call will not throw an error. Instead, it will stay in the default state where every feature evaluates to null.
You can still get access to the error if needed:
- success -
trueif the GrowthBook instance was populated with features/experiments. Otherwisefalse - source - Where this result came from. One of the following values:
network,cache,init,error, ortimeout - error - If success is
false, this will contain anErrorobject with more details about the error
Custom Integration
If you prefer to handle the network and caching logic yourself, you can pass in a full JSON “payload” directly into the SDK. For example, you might store features in Postgres and send it down to your front-end as part of your app’s initial bootstrap API call.setPayload(newPayloadJSON) and there are also getPayload() and getDecryptedPayload() methods, which are useful in hybrid apps where you want to hydrate the client with data from the server.
Note: you don’t need to specify clientKey or apiHost on your GrowthBook instance unless you want to enable streaming (see below) or call refreshFeatures() later.
Synchronous Init
There is a alternate synchronous version of init namedinitSync, which can be useful in some environments. There are some restrictions/differences:
- You MUST pass in
payload - The
payloadMUST NOT have encrypted features or experiments - If using sticky bucketing, you should use an instance of
StickyBucketServiceSync, such asBrowserCookieStickyBucketService. - The return value is the GrowthBook instance to enable easy method chaining
Streaming Updates
The GrowthBook SDK supports streaming with Server-Sent Events (SSE). When enabled, changes to features within GrowthBook will be streamed to the SDK in realtime as they are published. This is only supported on GrowthBook Cloud or if running a GrowthBook Proxy Server.Streaming in Browser Environments
SSE is supported on all major browsers, so enabling streaming is as easy as passingstreaming: true into your init call:
streamingHost property in the GrowthBook constructor (ex: Remote Evaluation is done on a CDN edge worker while Streaming is done through a GrowthBook Proxy server).
Remote Evaluation
See the Remote Evaluation overview for more information about what Remote Evaluation is, how it works, and deployment options.
remoteEval: true property to your SDK instance. A new evaluation API call will be made any time a user attribute or other dependency changes. You may optionally limit these API calls to specific attribute changes by setting the cacheKeyAttributes property (an array of attribute names that, when changed, trigger a new evaluation call).
If you would like to implement Sticky Bucketing while using Remote Evaluation, you must configure your remote evaluation backend to support Sticky Bucketing. In the case of the GrowthBook Proxy Server, this means implementing a Redis database for sticky bucketing use. You will not need to provide a StickyBucketService instance to the client side SDK.
Caching
The JavaScript SDK has 2 caching layers:- In-memory cache (available on all platforms)
- Persistent localStorage cache (only available in browsers by default)
configureCache with a subset of these fields and the rest will keep their default values.
Re-rendering When Features Change
When features change (e.g. by callinggb.refreshFeatures()), you need to re-render your app so that all of your feature flag checks can be re-evaluated. You can specify your own custom rendering function for this purpose:
Experimentation (A/B Testing)
In order to run A/B tests, you need to set up a tracking callback function. This is called every time a user is put into an experiment and can be used to track the exposure event in your analytics system (Segment, Mixpanel, GA, etc.). Note: If you use thethird-party-tracking plugin, you don’t need to specify a trackingCallback since the plugin will handle that for you automatically.
Feature Flag Experiments
There is nothing special you have to do for feature flag experiments. Just evaluate the feature flag like you would normally do. If the user is put into an experiment as part of the feature flag, it will call thetrackingCallback automatically in the background.
result.featureId in the trackingCallback will contain the feature id, which may be useful for tracking/logging purposes.
Visual Editor Experiments
Experiments created through the GrowthBook Visual Editor will run automatically as soon as their targeting conditions are met. Note: Visual Editor experiments are only supported in a web browser environment. They will not run in Node.js, Mobile apps, or Desktop apps. If you are using this SDK in a Single Page App (SPA), you will need to let the GrowthBook instance know when the URL changes so the active experiments can update accordingly.- disableVisualExperiments - If true, all visual editor experiments will be skipped
- disableJsInjection - If true, any visual editor experiment that injects custom javascript will be skipped.
Content Security Policy
If you plan to use the Custom Javascript feature of the Visual Editor and you have a Content Security Policy on your site, there are two options:- Enable
unsafe-inlinescript-src - OR generate a unique nonce value, add it to your script-src directive, and pass it into the GrowthBook constructor as
jsInjectionNonce
URL Redirect Experiments
Similarly to Visual Editor experiments, URL redirect tests will run automatically if targeting conditions are met. If you are using this SDK in a Single Page App (SPA), you’ll want to pass in a custom navigation function into the SDK (as default navigation for URL Redirects useswindow.location.replace(url)) and set the navigateDelay to 0.
- disableUrlRedirectExperiments - If true, all URL Redirect experiments will be skipped
- disableCrossOriginUrlRedirectExperiments - If true, any URL Redirect with a destination pointing to a different origin will be skipped.
Deferred Tracking
Sometimes, your analytics tracker is loaded after GrowthBook. In that case, you should not specify atrackingCallback in the constructor and instead use setTrackingCallback later when ready. When you do this, the GrowthBook instance will queue up tracking calls and then fire them all at once when you set the callback.
There are some scenarios where you need to queue up tracking calls in one GrowthBook instance and fire them in another. For example, if your analytics tracker is only available on the front-end, but you are running experiments in Node.js.
Export the queue tracking calls with the getDeferredTrackingCalls() method. The result is a serializable JSON object:
setDeferredTrackingCalls. This does not fire them automatically. You must call fireDeferredTrackingCalls after.
Sticky Bucketing
Sticky bucketing ensures that users see the same experiment variant, even when user session, user login status, or experiment parameters change. See the Sticky Bucketing docs for more information. If your organization and experiment supports sticky bucketing, you must implement an instance of theStickyBucketService to use Sticky Bucketing. The JS SDK exports several implementations of this service for common use cases, or you may build your own:
LocalStorageStickyBucketService— For simple bucket persistence using the browser’s LocalStorage (can be polyfilled for other environments).BrowserCookieStickyBucketService— For simple bucket persistence using browser cookies, which are transportable to the back end. Assumesjs-cookieis implemented (can be polyfilled). Cookie attributes can also be configured. The default cookie expiry is 180 days; override by passingexpires: {days}into the constructor’scookieAttributes.- Build your own — Implement the abstract
StickyBucketServiceclass and connect to your own data store, or custom wrap multiple service implementations (ex: read/write to both cookies and Redis).
BrowserCookieStickyBucketService:
TypeScript
When used in a TypeScript project, GrowthBook includes basic type inference out of the box:Strict Typing
If you want to enforce stricter types in your application, you can do that when creating the GrowthBook instance:AppFeatures interface manually like above, you can auto-generate it from your GrowthBook account using the GrowthBook CLI.
Updating
As a general philosophy, we aim to keep the SDK 100% backwards compatible at all times. View the Changelog for a complete list of all SDK changes.Updating to 1.0.0
Updating from a 0.X.X release to 1.0.0 is still backwards compatible for the vast majority of use cases, although there are a few minor changes:- The
enableDevMode: truesetting previously also disabled cache as a side-effect. This is no longer the case in 1.0.0, and you must explicitly also setdisableCache: true - Previously, a network request to fetch features was started immediately upon creating a GrowthBook instance. Starting in 1.0.0, it waits until you call
loadFeatures(or the newinitmethod) before starting the network request. As a replacement, there is now a standaloneprefetchPayloadfunction that you can use to kick off a network request outside of the context of a GrowthBook instance.
Switching to init
GrowthBook 1.0.0 introduced a newinit (and initSync) method.
We recommend everyone starts using this in their implementation. It solves many pain points including easier error handling and more control over caching and streaming.
For those currently using loadFeatures, init is a direct replacement. The only difference is that streaming is now opt-in instead of on-by-default.
loadFeatures and passing features/experiments directly into the GrowthBook constructor, init and initSync can be used instead. The code below assumes you have a payload variable with the contents from the SDK Connection Endpoint.
GrowthBook Instance (reference)
Attributes
You can specify attributes about the current user and request. These are used for two things:- Feature targeting (e.g. paid users get one value, free users get another)
- Assigning persistent variations in A/B tests (e.g. user id “123” always gets variation B)
Updating Attributes
If attributes change, you can callsetAttributes() to update. This will completely overwrite any existing attributes. To do a partial update, use the following pattern:
Secure Attributes
When secure attribute hashing is enabled, all targeting conditions in the SDK payload referencing attributes with datatypesecureString or secureString[] will be anonymized via SHA-256 hashing. This allows you to safely target users based on sensitive attributes. You must enable this feature in your SDK Connection for it to take effect.
If your SDK Connection has secure attribute hashing enabled, you will need to manually hash any secureString or secureString[] attributes that you pass into the GrowthBook SDK.
To hash an attribute, use a cryptographic library with SHA-256 support, and compute the SHA-256 hashed value of your attribute plus your organization’s secure attribute salt.
The example below is using CryptoJS (crypto-js), which provides a synchronous API.
setAttributes since SubtleCrypto methods are async. Here’s an example implementation:
Feature Usage Callback
GrowthBook can fire a callback whenever a feature is evaluated for a user. This can be useful to update 3rd party tools like NewRelic or DataDog.result argument is the same thing returned from gb.evalFeature.
Note: If you evaluate the same feature multiple times (and the value doesn’t change), the callback will only be fired the first time.
Dev Mode
There is a GrowthBook Chrome DevTools Extension that can help you debug and test your feature flags in development. In order for this to work, you must explicitly enable dev mode when creating your GrowthBook instance:false in production in most cases.
evalFeature
In addition to theisOn and getFeatureValue helper methods, there is the evalFeature method that gives you more detailed information about why the value was assigned to the user.
Inline Experiments
Instead of declaring all features up-front in the context and referencing them by ids in your code, you can also just run an experiment directly. This is done with thegb.run method:
Customizing the Traffic Split
By default, this will include all traffic and do an even split between all variations. There are 2 ways to customize this behavior:Hashing
We use deterministic hashing to assign a variation to a user. We hash together the user’s id and experiment key, which produces a number between0 and 1. Each variation is assigned a range of numbers, and whichever one the user’s hash value falls into will be assigned.
You can customize this hashing behavior:
hashVersion is specified, it will fall back to using version 1, which is deprecated. In the future, version 2 will become the default. We recommend specifying version 2 now for all new experiments to avoid migration issues down the line.
Meta Info
You can also define meta info for the experiment and/or variations. These do not affect the behavior, but they are passed through to thetrackingCallback, so they can be used to annotate events.
Mutual Exclusion
Sometimes you want to run multiple conflicting experiments at the same time. You can use thefilters setting to run mutually exclusive experiments.
We do this using deterministic hashing to assign users a value between 0 and 1 for each filter.
Holdout Groups
To use global holdout groups, use a nested experiment design:Targeting Conditions
You can also define targeting conditions that limit which users are included in the experiment. These conditions are evaluated against theattributes passed into the GrowthBook context. The syntax for conditions is based on the MongoDB query syntax and is straightforward to read and write.
For example, if the attributes are:
true and the user would be included in the experiment:
Inline Experiment Return Value
A call togb.run(experiment) returns an object with a few useful properties:
inExperiment flag will be false if the user was excluded from being part of the experiment for any reason (e.g. failed targeting conditions).
The hashUsed flag will only be true if the user was randomly assigned a variation. If the user was forced into a specific variation instead, this flag will be false.
Feature Definitions (reference)
The feature definition JSON file contains information about all of the features in your application. Each feature consists of a unique key, a list of possible values, and rules for how to assign those values to users.Basic Feature
An empty feature always has the valuenull:
Default Values
You can change the default assigned value with thedefaultValue property:
Rules
You can override the default value with Rules. Rules give you fine-grained control over how feature values are assigned to users. There are 2 types of feature rules:force and experiment. Force rules give the same value to everyone. Experiment rules assign values to users randomly.
Rule Ids
Rules can specify a unique identifier with theid property. This can help with debugging and QA by letting you see exactly why a specific value was assigned to a user.
Rule Conditions
Rules can optionally define targeting conditions that limit which users the rule applies to. These conditions are evaluated against theattributes passed into the GrowthBook context. The syntax for conditions is based on the MongoDB query syntax and is straightforward to read and write.
For example, if the attributes are:
true:
false, the rule will be skipped. This means you can chain rules together with different conditions to support even the most complex use cases.
Force Rules
Force rules do what you’d expect - force a specific value for the featureGradual Rollouts
You can specify arange for your rule, which determines what percent of users will get the rule applied to them. Users who do not get the rule applied will fall through to the next matching rule (or default value). You can also specify a seed that will be used for hashing.
In order to figure out if a user is included or not, we use deterministic hashing. By default, we use the user attribute id for this, but you can override this by specifying hashAttribute for the rule:
This is useful for gradually rolling out features to users (start with a small range and slowly increase).
Experiment Rules
Experiment rules let you adjust the percent of users who get randomly assigned to each variation. This can either be used for hypothesis-driven A/B tests or to simply mitigate risk by gradually rolling out new features to your users.Customizing the Traffic Split
By default, an experiment rule will include all traffic and do an even split between all variations. There are 2 ways to customize this behavior:Variation Meta Info
You can use themeta setting to provide additional info about the variations such as name.
Tracking Key and Name
When a user is assigned a variation, we call thetrackingCallback function so you can record the exposure with your analytics event tracking system. By default, we use the feature id to identify the experiment, but this can be overridden if needed with the key setting. You can also optionally provide a human-readable name.
Hash Attribute
We use deterministic hashing to make sure the same user always gets assigned the same value. By default, we use the attributeid, but this can be overridden with the hashAttribute setting:
Filters
Sometimes you want to run multiple conflicting experiments at the same time. You can use thefilters setting to run mutually exclusive experiments.
We do this using deterministic hashing to assign users a value between 0 and 1 for each filter.

