This article helps you:
Setup the SDK and deployment for your experiments
Create feature flags, variants, and payloads
Design and implement the experiment
Experiment is a workflow-driven behavioral experimentation platform that accelerates the process of creating different variants of features and websites for experimentation.
With Experiment, you can modify and configure product experiences for unique audiences through:
Experiment enables experimentation through feature flags. Feature flags are switches that let you modify your product's experience without having to change code. Experiments and feature flags use the Amplitude Experiment SDK or REST API to communicate with Amplitude Experiment.
Setting up an experiment is a multi-stage process encompassing the following procedures:
Before you can begin using experiments:
Install the Amplitude SDK with the Experiment client. For example:
npm install @amplitude/analytics-browser @amplitude/experiment-browser
import * as amplitude from '@amplitude/analytics-browser';
import { Experiment } from '@amplitude/experiment-browser';
amplitude.init('AMPLITUDE_API_KEY');
const experiment = Experiment.initialize('DEPLOYMENT_API_KEY');
await experiment.start();
Experiment uses the same projects as Amplitude Analytics. As a best practice, create one project for each product and each environment. Because flags, experiments, and deployments only exist within a single project, you must duplicate these objects across projects within the same product.
In Amplitude Experiment, a deployment serves a group of flags or experiments for use in an application. Each project has a deployment using the project API key as the deployment key, available by default. On creation, a randomly generated deployment key is assigned to each deployment, which Experiment uses to identify the deployment and authorize requests to the evaluation servers.
Deployments belong to Amplitude Analytics projects, and a project can have multiple deployments. Amplitude recommends that you name deployments after the platform (client-side) or service (server-side) to which Experiment serves variants (for example: android
, ios
, web
). The default project API key deployment is useful for getting started. However, you may find it useful to use explicit deployments for each platform or service for larger organizations or teams that may share the same Amplitude project across multiple platforms for the same application. Each deployment receives a unique key for use in your application.
A flag is a way for you to enable or disable a function or feature in your product, without having to deploy new code each time. Flags drive both experiments and feature rollouts. They're ideal for launching experiments and ending them after you’ve collected enough data or for rolling out new features (and rolling them back, if needed).
Go to Experiment > Feature Flags.
Click Create Feature Flag.
In the Create Flag section, select the project yoou want from the dropdown list and then give your flag a name.
Amplitude Experiment generates the flag key from the name you choose. The flag key is an identifier for the flag used in your codebase.
Specify the evaluation mode for your experiment. Select either Remote or Local.
Specify the bucketing unit you want to use for this experiment.
Click Create.
Experiment opens a blank template for your flag.
Choose the deployment you want from the Deployment dropdown menu.
(Optional) Click Advanced Settings to modify the bucketing salt options.
A variant exists within a flag or an experiment, and represents a variable experience for a user. Variants comprise the actual A/B changes that you want to experiment with. All feature flags must contain at least one variant. You can add as many variants as you want to a flag.
Add JSON content to the Payload field when creating a variant. Payload content is similar to:
{
"layout": "cards",
"titlePosition": "above",
"gradient": false,
"showDescription": true,
"cardCount": 3
}
After you set up the flag, associate it to a deployment, set up your variants or payloads, and target your users, finalize the feature flag.
Finalizing the flag activates it and makes it available.
After you convert your flag to an experiment, finalize the experiment. To finalize an experiment:
Adding goals (or metrics) lets you track the success rate of your experiment. All experiments should have at least one goal. Tell Amplitude Experiment what you want your recommendation metric to be, as well as define any secondary metrics. The recommendation metric determines whether your hypothesis is accepted or rejected, and therefore, whether your experiment has succeeded or failed.
Repeat the steps above in your flag to create additional variations and payloads.
After you have completed designing your experiment, click Start Experiment to begin.
The following code examples describe the code for a feature flag and a JSON payload:
import { useState, useEffect } from 'react';
import { getBlogLayoutFlag } from '../services/featureFlags'; // Adjust to wherever you fetch your Amplitude flag
import type { BlogPost } from '../types';
type LayoutFlag = {
layout: 'cards' | 'list' | 'carousel';
titlePosition: 'above' | 'below' | 'center';
gradient: boolean;
showDescription: boolean;
cardCount: number;
};
export default function BlogPostLayoutClient({ posts }: { posts: BlogPost[] }) {
const [layoutFlag, setLayoutFlag] = useState<LayoutFlag | null>(null);
useEffect(() => {
getBlogLayoutFlag().then((flag) => {
console.log(':magic_wand: Received Flag from Amplitude:', flag);
if (flag) {
setLayoutFlag(flag);
} else {
console.log(':warning: No flag returned, falling back to default layout');
setLayoutFlag({
layout: 'cards',
titlePosition: 'above',
gradient: false,
showDescription: true,
cardCount: 3,
});
}
});
}, []);
if (!layoutFlag) {
// You might render a loader here
return null;
}
// Render your posts according to layoutFlag...
return (
<div>
{/* e.g. layoutFlag.layout === 'cards' ? <CardGrid posts={posts} /> : ... */}
</div>
);
}
// services/featureFlags.ts
import { experiment } from '@amplitude/experiment-js'; // adjust import to your SDK
import type { LayoutFlag } from '../types'; // reuse the same LayoutFlag type
export const getBlogLayoutFlag = async (): Promise<LayoutFlag> => {
try {
// In dev, clear any stale flags
if (process.env.NODE_ENV === 'development') {
localStorage.clear();
console.warn('Cleared localStorage in dev mode');
}
// Initialize the experiment SDK
await experiment.start();
// Grab the variant for our blog layout test
const variant = experiment.variant('blog_post_layout');
console.log(':movie_camera: Full Variant Object:', variant);
// Some payloads come in `payload`, some in `value`
const value = variant?.payload ?? variant?.value;
console.log('Cleaned Flag Payload:', value);
// If there's no usable object, fall back to defaults
if (!value || typeof value !== 'object' || Object.keys(value).length === 0) {
console.warn('No valid layout flag found, using fallback layout');
return {
layout: 'carousel',
titlePosition: 'above',
gradient: false,
showDescription: true,
cardCount: 3,
};
}
// Otherwise assume it's Amplitude's LayoutFlag shape
return value as LayoutFlag;
} catch (error) {
console.error('Error fetching blog layout flag:', error);
// On error, also fall back
return {
layout: 'carousel',
titlePosition: 'above',
gradient: false,
showDescription: true,
cardCount: 3,
};
}
};
July 21st, 2025
Need help? Contact Support
Visit Amplitude.com
Have a look at the Amplitude Blog
Learn more at Amplitude Academy
© 2025 Amplitude, Inc. All rights reserved. Amplitude is a registered trademark of Amplitude, Inc.