# Feature flags (/docs/feature-flags)

A feature flag is a key your code checks, such as `new-checkout`. In Datahop you decide who gets it, and you can change that at any time without a deploy.

- **Boolean flags** are on or off: *turn the new checkout on for 10% of users*.
- **Multivariate flags** return a variant, such as `control`, `compact` or `wide`, each with its own share and an optional payload. [Experiments](/docs/experiments) run on these.

```ts
if (datahop.isFeatureEnabled('new-checkout')) showNewCheckout()
```

## Create a flag [#create-a-flag]

**Feature flags → New flag.**

1. Set a **Key** (letters, numbers, `-` and `_`), and optionally a name and description.
2. Set the **Release conditions**: who gets the flag. See below.
3. Choose the **Served value**: **Boolean** or **Multivariate**.
4. Optionally add **Payloads**.
5. Switch it on. New flags start off.

The **Implementation** panel shows a ready-to-copy snippet for your code, with a Copy Prompt for your coding agent. See [Flags in your code](/docs/feature-flags/in-code).

## Who gets it [#who-gets-it]

Release conditions are a list of **condition sets**, checked from top to bottom. Each set has:

- **conditions**, which must all match. No conditions means everyone.
- a **rollout percentage**: the share of matching people who get the flag.

A person gets the flag from the first set they match *and* whose rollout includes them. Otherwise Datahop checks the next set. Nobody matched? The flag is off for them. So put specific rules on top and the broad catch-all at the bottom:

1. Email contains `@yourcompany.com`, 100%: the team always sees it.
2. In cohort *Power users*, 50%.
3. Everyone, 5%.

Conditions can check:

- **Person properties**, such as `plan` equals `pro` or `country` is one of `DE, NL`. These are the properties you set with [`identify`](/docs/getting-started/identify#person-properties).
- **Cohorts**, in or not in. This is how you target behaviour, such as *power users* or *people who haven't ordered in 90 days*. Cohort changes reach flags within about five minutes.
- **Group properties**, when the flag [matches by company](#match-by-company).

People Datahop hasn't seen yet are never in a cohort.

### Rollout percentages are stable [#rollout-percentages-are-stable]

- **The same person always gets the same value**, on every device and after they log in.
- **Raising the rollout only adds people.** Going from 10% to 30% keeps the first 10%, so nobody flips back and forth.
- **Flags are independent.** Being in the first 10% of one flag says nothing about another.

## Variants [#variants]

Choose **Served value → Multivariate** and add variants with a key and a share. The shares must add up to 100. Everyone a condition set lets in gets one variant, and keeps it.

A condition set can also **Force** one variant instead of **Split by variant percentages**. Use it to always show the team the new version, or to keep a segment on `control`.

Changing the shares later moves some people to another variant. Don't do that during a running experiment.

## Payloads [#payloads]

A payload is a piece of JSON attached to a variant, or to "on" for a boolean flag. Use it for copy, limits or settings you want to change without a deploy:

```json
{ "compact": { "columns": 1 }, "wide": { "columns": 3 } }
```

```ts
const layout = datahop.getFeatureFlagPayload('board-layout') as { columns: number } | undefined
```

## Match by company [#match-by-company]

Set **Match by** to a group type, such as company, to decide the flag **per account** instead of per person. Then everyone at Acme gets the same value, which is usually what B2B features need, because half a team seeing a feature is a support problem.

Conditions can then check the company's properties, such as `plan` equals `enterprise`. Your app has to tell Datahop the company with [`group()`](/docs/getting-started/identify#groups-companies-workspaces-teams). Without a company, the flag is off.

## Test a user [#test-a-user]

Before you widen a rollout, open the flag and use **Test a user**. Enter an id or email to see this flag's value and payload for that person, plus every other flag they'd get.

## Turn it off [#turn-it-off]

Switching a flag off turns it off for everyone immediately. It's your kill switch. Your code then sees the flag as unknown, so always have a default path.

## Flags used by experiments [#flags-used-by-experiments]

Every experiment creates its own flag. While the experiment runs, you can't change its variant keys, and the flag can't be deleted. When you conclude an experiment, you can roll the winner out to everyone through the same flag, and your code keeps working unchanged.
