A Claude Code subagent that automates the migration from the Statsig SDK to GrowthBook SDK. Focused on JavaScript/React Client SDKs to start.
This agent helps developers migrate their feature gate, dynamic config, and user context implementations from Statsig to GrowthBook by:
- Converting import statements to GrowthBook SDK
- Converting feature gates to boolean flags with proper fallback handling
- Migrating dynamic configs to feature values with appropriate fallback values
- Transforming StatsigUser objects to GrowthBook attributes (flattened structure)
- Identifying compatibility issues and required manual interventions
- Providing migration guidance for SDK initialization and user context
.
├── .claude/
│ └── agents/
│ └── statsig-to-growthbook-sdk-migrator.md # The Claude Code agent
├── tests/
│ ├── examples/ # Example migration cases
│ └── fixtures/ # Test input/output files
├── README.md # This documentation
├── LICENSE # MIT License
└── .gitignore # Git ignore rules
Note: Only the statsig-to-growthbook-sdk-migrator.md file is needed for Claude Code. The tests directory contains examples and test cases for validation.
// Core SDK - CommonJS
const statsig = require('statsig-js');
// →
const { GrowthBook } = require('@growthbook/growthbook');
// Core SDK - ES2015/ES6 Modules
import statsig from 'statsig-js';
// →
import { GrowthBook } from '@growthbook/growthbook';
// TypeScript
import { Statsig, StatsigUser } from 'statsig-js';
// →
import { GrowthBook } from '@growthbook/growthbook';
// Use GrowthBook's built-in types
// React SDK - Statsig
import { StatsigProvider, useGateValue } from '@statsig/react-bindings';
import { useStatsigClient, useExperiment } from '@statsig/react-bindings';
// → GrowthBook React
import { GrowthBookProvider, useFeatureIsOn, useFeatureValue } from '@growthbook/growthbook-react';
// Observability - ONLY if customer uses autocapture/session replay
// Statsig (built-in or separate packages):
import { StatsigAutocapture } from '@statsig/web-analytics';
import { StatsigSessionReplay } from '@statsig/session-replay';
// → GrowthBook (uses plugins/callbacks):
import { autoAttributesPlugin, thirdPartyTrackingPlugin } from "@growthbook/growthbook/plugins";// Statsig
if (statsig.checkGate("new_feature")) { }
// GrowthBook - JavaScript SDK
if (gb.isOn("new_feature")) { }
// GrowthBook - React SDK
const isEnabled = useFeatureIsOn('new_feature');
if (isEnabled) { }// Statsig
const config = statsig.getConfig("homepage_config");
const title = config.get("title", "Default");
// GrowthBook - JavaScript SDK
const config = gb.getFeatureValue("homepage_config", { title: "Default" });
const title = config.title;
// GrowthBook - React SDK
const config = useFeatureValue('homepage_config', { title: "Default" });
const title = config.title;StatsigUser objects must be transformed to GrowthBook attributes (flattened structure):
userID→id(required)customproperties → flattened to top levelcustomIDs→ flattened to top levelprivateAttributes→ handled differently (GrowthBook doesn't have built-in private attributes)
// Statsig User
const statsigUser = {
userID: "user-123",
email: "anna@example.com",
custom: { organization: "Global Health", tier: "premium" },
customIDs: { orgID: "org-456" },
privateAttributes: { salary: 100000 }
};
// GrowthBook Attributes (flattened structure)
const gbAttributes = {
id: "user-123", // Maps from userID
email: "anna@example.com",
organization: "Global Health", // custom properties flattened
tier: "premium",
orgID: "org-456", // customIDs flattened
// Note: privateAttributes need alternative handling in GrowthBook
};// Statsig initialization
await Statsig.initialize('client-key', {
userID: 'user-123',
email: 'user@example.com',
custom: { plan: 'premium' }
});
// GrowthBook initialization with plugins
const gb = new GrowthBook({
apiHost: 'https://cdn.growthbook.io',
clientKey: 'sdk-YOUR_CLIENT_KEY', // TODO: Replace with actual GrowthBook client key
plugins: [
autoAttributesPlugin(),
thirdPartyTrackingPlugin(),
],
});
await gb.init();
// GrowthBook initialization with custom tracking
const gb = new GrowthBook({
apiHost: "https://cdn.growthbook.io",
clientKey: "sdk-abc123",
attributes: {
id: "123",
country: "US"
},
trackingCallback: (experiment, result) => {
console.log("Experiment Viewed", {
experimentId: experiment.key,
variationId: result.key,
});
},
});
await gb.init();CRITICAL: GrowthBook requires a different client key than Statsig:
- DO NOT use your Statsig SDK key (
client-xxx) - DO use your GrowthBook Client Key (
sdk-xxx) - Client keys are incompatible between platforms
Important: GrowthBook handles fallback values differently:
- Boolean flags: GrowthBook handles defaults via dashboard configuration
- JSON/object flags: Provide appropriate fallback values in
getFeatureValuecalls - Default values are configured in the GrowthBook UI, not in code
Key Difference: GrowthBook uses a flattened attribute structure:
- Statsig's
customobject properties are flattened to top-level in GrowthBook customIDsare also flattened to top-level attributes- All attributes are used for targeting and experiment assignment
- Attributes can be updated dynamically with
updateAttributes()
Important: Most experiments in GrowthBook are run via feature flags:
gb.isOn("gate_name")will run the experiment included on that gate- Visual Editor experiments and URL redirects run automatically
- Inline experiments (defined in code) are less common but supported
// Statsig
const experiment = statsig.getExperiment('button_color_test');
const buttonColor = experiment.get('color', 'blue');
// GrowthBook - Remote experiment (most common)
const buttonColor = gb.getFeatureValue('button_color_test', 'blue');
// GrowthBook - Inline experiment (less common)
const { value: buttonColor } = gb.run({
key: 'button_color_test',
variations: ['blue', 'red', 'green']
});// Statsig Provider Pattern
import { StatsigProvider } from '@statsig/react-bindings';
<StatsigProvider
sdkKey="client-KEY"
user={{ userID: "123", email: "user@example.com" }}
loadingComponent={<Loading />}
>
<App />
</StatsigProvider>
// GrowthBook Provider Pattern
import { useEffect } from "react";
import { GrowthBook, GrowthBookProvider } from "@growthbook/growthbook-react";
const gb = new GrowthBook({
apiHost: "https://cdn.growthbook.io",
clientKey: "sdk-abc123",
enableDevMode: true,
trackingCallback: (experiment, result) => {
console.log("Experiment Viewed", {
experimentId: experiment.key,
variationId: result.key,
});
},
});
await gb.init();
export default function App() {
useEffect(() => {
gb.setAttributes({
id: user.id,
company: user.company,
});
}, [user])
return (
<GrowthBookProvider growthbook={gb}>
<OtherComponent />
</GrowthBookProvider>
);
}- Client Key: Use GrowthBook client key, NOT Statsig SDK key
- Fallback Values: Provide appropriate fallback values for feature value calls
- Attribute Structure: Flatten custom properties to top-level attributes
- Experiments: Most are handled via feature flags, not separate experiment methods
- Analytics: GrowthBook doesn't have built-in event logging - integrate with external service
- Built-in analytics (requires external service integration)
- Session replay (GrowthBook doesn't support this feature)
- Complex targeting rules (require manual GrowthBook dashboard configuration)
- Statsig-specific features without direct GrowthBook equivalents
This agent is designed to be used with Claude Code. You only need to download the agent file to your local .claude/agents/ directory.
# Create the agents directory if it doesn't exist
mkdir -p ~/.claude/agents/
# Download the agent file directly from this repository
curl -o ~/.claude/agents/statsig-to-growthbook-sdk-migrator.md \
https://raw.githubusercontent.com/growthbook/claude-statsig-to-growthbook-sdk-migrator/main/.claude/agents/statsig-to-growthbook-sdk-migrator.mdmkdir -p ~/.claude/agents/
wget -O ~/.claude/agents/statsig-to-growthbook-sdk-migrator.md \
https://raw.githubusercontent.com/yeutterg/claude-statsig-to-growthbook-sdk-migrator/main/.claude/agents/statsig-to-growthbook-sdk-migrator.md- Navigate to
.claude/agents/statsig-to-growthbook-sdk-migrator.mdin this repository - Click "Raw" to view the raw file
- Save the file to your local
~/.claude/agents/directory - Ensure the file has the
.mdextension
After downloading, you can verify the agent is installed:
ls -la ~/.claude/agents/statsig-to-growthbook-sdk-migrator.mdThe agent will be immediately available in Claude Code. If Claude Code is already running, you may need to restart it.
When working with Claude Code, you can invoke the agent when you need to migrate Statsig code:
"I need to migrate this code from the Statsig SDK to the GrowthBook SDK: [filename]"
The agent will:
- Analyze your Statsig implementation
- Convert feature gates and dynamic configs to GrowthBook
- Transform user context to GrowthBook attributes
- Provide migration notes and warnings
- Generate a detailed migration report (JSON)
- List manual steps required
- Suggest verification steps
The agent generates a migration-summary.json file containing:
- Summary statistics (total items, migrated, manual intervention required, failed)
- Detailed list of migrated feature gates and configs
- List of items requiring manual intervention with reasons
- Warnings about compatibility issues
- Clear next steps for completing migration
Example report structure:
{
"timestamp": "2024-01-15T10:30:00Z",
"client_key_warning": "REPLACE_WITH_GROWTHBOOK_CLIENT_KEY",
"summary": {
"total_items": 25,
"successfully_migrated": 23,
"manual_intervention_required": 2,
"failed": 0
},
"migrated": {
"feature_gates": [
{
"statsig_name": "new_dashboard",
"gb_name": "new_dashboard",
"type": "boolean",
"method_change": "checkGate() → isOn()"
}
]
}
}- Inventory all Statsig feature gates and dynamic configs
- Document current flag states and configurations
- Obtain GrowthBook client key (DO NOT use Statsig SDK key)
- Map all user properties and custom IDs
- Identify any custom analytics integrations
- Plan timeline for dashboard configuration
- Client Key Verification: Ensure GrowthBook client key is properly configured
- Fallback Testing: Verify behavior when flags are unavailable
- Attribute Testing: Confirm user attributes are properly set
- Performance Monitoring: Check SDK initialization time and flag evaluation latency
describe('Migration Validation', () => {
test('Boolean flags return correct values', async () => {
const result = gb.isOn('test-flag');
expect(typeof result).toBe('boolean');
});
test('Feature values return fallback when unavailable', async () => {
const fallback = { enabled: false, title: "Default" };
const result = gb.getFeatureValue('missing-config', fallback);
expect(result).toEqual(fallback);
});
});- GrowthBook JavaScript SDK
- Claude Code for agent usage
For issues or questions about this migration agent:
- Create an issue at https://github.com/yeutterg/claude-statsig-to-growthbook-sdk-migrator/issues
- Consult the official documentation:
Contributions are welcome! Please submit pull requests with:
- Updated migration patterns
- Additional test cases
- Documentation improvements
- Bug fixes