> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useshipd.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from Statsig

> Map Statsig gates, experiments, and dynamic configs to shipd flags, and move them over one at a time.

## Overview

This page maps Statsig concepts to shipd and shows a manual migration path. shipd has no automated importer: you recreate definitions in TypeScript or Go, recreate targeting in the dashboard, and switch code over one gate or config at a time.

shipd assigns variants but doesn't compute experiment results. Keep sending exposures and metrics to your analytics tool.

## Concept mapping

| Statsig | shipd |
| - | - |
| Feature gate | Boolean flag (`type: "boolean"`) → [`isEnabled`](/reference/sdk#isenabled) |
| Gate rules | Rules on the flag page. First match wins |
| Gate pass percentage | **Percentage** condition ([rollouts](/flags/percentage-rollouts)) |
| Experiment groups | Variant flag (`type: "variant"`) with a percentage split ([A/B tests](/flags/experiments)) |
| Layers | No equivalent. Use one variant flag per experiment |
| Dynamic config | JSON flag (`type: "json"`) → [`getJson`](/reference/sdk#getjson) |
| Parameter that is a number | Number flag (`type: "number"`) → [`getNumber`](/reference/sdk#getnumber) |
| Segments | Audiences |
| `StatsigUser` | [Evaluation context](/reference/sdk#types) |
| `userID` | `userId` |
| `email`, `country`, `custom` fields | `attributes` |
| `customIDs` | `attributes`, with the percentage condition's **Of attribute** set to bucket on them |
| Server secret key | Server SDK key (`shipd_sdk_server_…`) |
| Client SDK key | Client SDK key (`shipd_sdk_client_…`) |
| Pulse / experiment results | Not provided. Analyze in your own analytics |

## Map the user object

```ts TypeScript theme={null}
// Statsig
const user = {
  userID: "usr_8f2k19",
  email: "dana@fieldkit.dev",
  country: "US",
  custom: { plan: "pro" },
  customIDs: { companyID: "org_fieldkit" },
};

// shipd
const context = {
  userId: "usr_8f2k19",
  attributes: {
    email: "dana@fieldkit.dev",
    country: "US",
    plan: "pro",
    companyID: "org_fieldkit",
  },
};
```

```go Go theme={null}
// Map Statsig's userID to UserID; other user fields become Attributes.
user := shipd.EvaluationContext{
    UserID: "usr_8f2k19",
    Attributes: map[string]any{
        "email": "dana@fieldkit.dev", "country": "US", "plan": "pro",
        "companyID": "org_fieldkit",
    },
}
```

Browser clients (`shipdit/client`) fill `country`, `region`, `city`, and `timezone` automatically. See [Target users by attribute](/flags/targeting).

## Migrate

**1. Recreate definitions**

```ts TypeScript theme={null}
// shipd.config.ts
import { defineFlags } from "shipdit/config";

export default defineFlags({
  // gate: new_checkout
  "new-checkout": { type: "boolean", default: false },
  // experiment: search_ranking
  "search-variant": {
    type: "variant",
    variants: ["control", "semantic", "hybrid"] as const,
    default: "control",
  },
  // dynamic config: checkout_config
  "checkout-payload": {
    type: "json",
    default: { mode: "strict", showPromo: true },
  },
});
```

```go Go theme={null}
// Entries inside config.ShipdConfig (import github.com/alasti-company/useshipd.com/sdks/go/config).
"new-checkout": {Type: "boolean", Default: false},
"search-variant": {Type: "variant", Default: "control",
    Variants: []string{"control", "semantic", "hybrid"}},
"checkout-payload": {Type: "json",
    Default: map[string]any{"mode": "strict", "showPromo": true}},
```

```bash theme={null}
shipd push --project web-app --env production
```

**2. Recreate targeting**

For each environment, open the flag in the [dashboard](https://app.useshipd.com), add rules in the same order as in Statsig, set **Fallthrough**, and click **Save environment**. Recreate segments under **Audiences** first.

**3. Replace calls**

```ts TypeScript theme={null}
// src/checkout.ts
// Before
const on = statsig.checkGate(user, "new_checkout");
const ranking = statsig.getExperiment(user, "search_ranking").get("variant", "control");
const config = statsig.getConfig(user, "checkout_config").value;

// After
const on = shipd.isEnabled("new-checkout", context);
const ranking = shipd.getVariant("search-variant", context);
const config = shipd.getJson("checkout-payload", context);
```

```go Go theme={null}
// Replace your existing Statsig evaluations with these local checks.
on := client.IsEnabled("new-checkout", user)
ranking := client.GetVariant("search-variant", user)
config := client.GetJSON("checkout-payload", user)
```

Wrap each check in one function and log mismatches between the two systems before you switch, as in the [LaunchDarkly guide](/resources/migrate-from-launchdarkly#migrate-a-flag).

**4. Keep logging exposures**

Log the variant to your analytics wherever you read it. See [Run an A/B test](/flags/experiments#read-the-variant-and-record-exposure).

Bucketing differs between tools, so users in a running Statsig experiment get new assignments in shipd. Start a new experiment period rather than migrating one mid-flight.

For Go definition snippets, add the entries to `config.ShipdConfig` in `shipd.config.go` before pushing. See [Define flags in code](/config-as-code/define-flags#go-definitions).

## Related

* [Quickstart](/quickstart)
* [Define flags in code](/config-as-code/define-flags)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.