Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 147 additions & 38 deletions skills/flags-sdk/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,34 @@
---
name: flags-sdk
description: >
Comprehensive guide for implementing feature flags and A/B tests using the Flags SDK (the `flags` npm package).
Use when: (1) Creating or declaring feature flags with `flag()`, (2) Setting up feature flag providers/adapters
(Vercel, Statsig, LaunchDarkly, PostHog, GrowthBook, Hypertune, Edge Config, OpenFeature, Flagsmith, Reflag,
Split, Optimizely, or custom adapters), (3) Implementing precompute patterns for static pages with feature flags,
(4) Setting up evaluation context with `identify` and `dedupe`, (5) Integrating the Flags Explorer / Vercel Toolbar,
(6) Working with feature flags in Next.js (App Router, Pages Router, Middleware) or SvelteKit,
(7) Writing custom adapters, (8) Encrypting/decrypting flag values for the toolbar,
(9) Any task involving the `flags`, `flags/next`, `flags/sveltekit`, `flags/react`, or `@flags-sdk/*` packages.
Comprehensive guide for implementing feature flags and A/B tests using the Flags SDK (the `flags` npm package)
and Vercel Flags (Vercel's feature flags platform, managed via dashboard or `vercel flags` CLI).
Use when: (1) Creating or declaring feature flags with `flag()`, (2) Using Vercel Flags with `vercelAdapter()` or
the `vercel flags` CLI (`add`, `list`, `enable`, `disable`, `inspect`, `archive`, `rm`, `sdk-keys`),
(3) Setting up feature flag providers/adapters (Vercel, Statsig, LaunchDarkly, PostHog, GrowthBook, Hypertune,
Edge Config, OpenFeature, Flagsmith, Reflag, Split, Optimizely, or custom adapters),
(4) Implementing precompute patterns for static pages with feature flags,
(5) Setting up evaluation context with `identify` and `dedupe`, (6) Integrating the Flags Explorer / Vercel Toolbar,
(7) Working with feature flags in Next.js (App Router, Pages Router, Middleware) or SvelteKit,
(8) Writing custom adapters, (9) Encrypting/decrypting flag values for the toolbar,
(10) Any task involving the `flags`, `flags/next`, `flags/sveltekit`, `flags/react`, or `@flags-sdk/*` packages.
Triggers on: feature flags, A/B testing, experimentation, flags SDK, flag adapters, precompute flags,
Flags Explorer, feature gates, flag overrides.
Flags Explorer, feature gates, flag overrides, Vercel Flags, vercel flags CLI, vercel flags add,
vercel flags list, vercel flags enable, vercel flags disable.
---

# Flags SDK

The Flags SDK (`flags` npm package) is a feature flags toolkit for Next.js and SvelteKit. It turns each feature flag into a callable function, works with any flag provider via adapters, and keeps pages static using the precompute pattern.
The Flags SDK (`flags` npm package) is a feature flags toolkit for Next.js and SvelteKit. It turns each feature flag into a callable function, works with any flag provider via adapters, and keeps pages static using the precompute pattern. Vercel Flags is the first-party provider, letting you manage flags from the Vercel dashboard or the `vercel flags` CLI.

- Docs: https://flags-sdk.dev
- Repo: https://github.com/vercel/flags

## Core Concepts
## Core concepts

### Flags as Code
### Flags as code

Each flag is declared as a function — no string keys at call sites:
Each flag is declared as a function. No string keys at call sites:

```ts
import { flag } from 'flags/next';
Expand All @@ -34,32 +38,132 @@ export const exampleFlag = flag({
decide() { return false; },
});

// Usage: just call the function
const value = await exampleFlag();
```

### Server-Side Evaluation
### Server-side evaluation

Evaluate flags server-side to avoid layout shift, keep pages static, and maintain confidentiality. Use routing middleware + precompute to serve static variants from CDN.
Flags evaluate server-side to avoid layout shift, keep pages static, and maintain confidentiality. Combine routing middleware with the precompute pattern to serve static variants from CDN.

### Adapter Pattern
### Adapter pattern

Adapters replace `decide` and `origin` on a flag declaration, enabling provider-agnostic flags:
Adapters replace `decide` and `origin` on a flag declaration, connecting your flags to a provider. Vercel Flags (`@flags-sdk/vercel`) is the first-party adapter. Third-party adapters are available for Statsig, LaunchDarkly, PostHog, and others.

```ts
import { flag } from 'flags/next';
import { statsigAdapter } from '@flags-sdk/statsig';
import { vercelAdapter } from '@flags-sdk/vercel';

export const myGate = flag({
key: 'my_gate',
adapter: statsigAdapter.featureGate((gate) => gate.value),
export const exampleFlag = flag({
key: 'example-flag',
adapter: vercelAdapter(),
});
```

## Vercel Flags

Vercel Flags is Vercel's feature flags platform. You create and manage flags from the Vercel dashboard or the `vercel flags` CLI, then connect them to your code with the `@flags-sdk/vercel` adapter. When you create a flag in Vercel, the `FLAGS` and `FLAGS_SECRET` environment variables are configured automatically.

### Quickstart

Install the adapter:

```bash
pnpm i flags @flags-sdk/vercel
```

Create a flag in the Vercel dashboard, then pull environment variables:

```bash
vercel env pull
```

You may need to run `vercel link` first if your project isn't linked to Vercel yet.

Declare the flag in your code:

```ts
// flags.ts
import { flag } from 'flags/next';
import { vercelAdapter } from '@flags-sdk/vercel';

export const exampleFlag = flag({
key: 'example-flag',
adapter: vercelAdapter(),
});
```

`vercelAdapter()` reads the `FLAGS` environment variable automatically. Call the flag as a function to resolve its value:

```tsx
// app/page.tsx
import { exampleFlag } from '../flags';

export default async function Page() {
const showExample = await exampleFlag();
return <div>{showExample ? 'Feature enabled' : 'Feature disabled'}</div>;
}
```

Toggle the flag in the Vercel dashboard for any environment (development, preview, production) and reload the page to see the change.

### User targeting

Target specific users or groups by providing an `identify` function. The returned entities are passed to Vercel Flags for rule evaluation:

```ts
import { dedupe, flag } from 'flags/next';
import { vercelAdapter } from '@flags-sdk/vercel';

type Entities = {
team?: { id: string };
user?: { id: string };
};

const identify = dedupe(async (): Promise<Entities> => ({
team: { id: 'team-123' },
user: { id: 'user-456' },
}));

export const exampleFlag = flag<boolean, Entities>({
key: 'example-flag',
identify,
adapter: vercelAdapter(),
});
```

## Declaring Flags
Configure which entity types are available for targeting in the Vercel Flags dashboard under your project's flags settings.

### `vercel flags` CLI

You can manage Vercel Flags from the terminal with `vercel flags`. The CLI supports creating, toggling, inspecting, archiving, and deleting flags, as well as managing SDK keys. It requires the [Vercel CLI](https://vercel.com/docs/cli) and a linked project (`vercel link`).

Available subcommands: `list`, `add`, `inspect`, `enable`, `disable`, `archive`, `rm`, `sdk-keys`.

For detailed examples and all subcommand options, see [references/providers.md](references/providers.md#vercel-flags-cli). For the full Vercel CLI reference (beyond flags), install the `vercel-cli` skill:

```bash
npx skills add https://github.com/vercel/vercel --skill vercel-cli
```

For advanced adapter configuration (custom SDK keys, singleton clients), see [references/providers.md](references/providers.md#vercel).

## Declaring flags

### With Vercel Flags (recommended)

Use `vercelAdapter()` to connect your flag to Vercel Flags. The adapter handles evaluation, so you don't need a `decide` function:

```ts
import { flag } from 'flags/next';
import { vercelAdapter } from '@flags-sdk/vercel';

export const exampleFlag = flag({
key: 'example-flag',
adapter: vercelAdapter(),
});
```

### Basic Flag
### Basic flag

```ts
import { flag } from 'flags/next'; // or 'flags/sveltekit'
Expand All @@ -76,9 +180,9 @@ export const showBanner = flag<boolean>({
});
```

### Flag with Evaluation Context
### Flag with evaluation context

Use `identify` to establish who the request is for; `decide` receives the entities:
Use `identify` to establish who the request is for. The returned entities are passed to `decide`:

```ts
import { dedupe, flag } from 'flags/next';
Expand All @@ -105,19 +209,24 @@ export const dashboardFlag = flag<boolean, Entities>({
});
```

### Flag with Adapter
### Flag with another adapter

Adapters connect flags to third-party providers. Each adapter replaces `decide` and `origin`:

```ts
import { flag } from 'flags/next';
import { vercelAdapter } from '@flags-sdk/vercel';
import { statsigAdapter } from '@flags-sdk/statsig';

export const exampleFlag = flag({
key: 'example-flag',
adapter: vercelAdapter(),
export const myGate = flag({
key: 'my_gate',
adapter: statsigAdapter.featureGate((gate) => gate.value),
identify,
});
```

### Key Parameters
See [references/providers.md](references/providers.md) for all supported adapters.

### Key parameters

| Parameter | Type | Description |
| -------------- | ---------------------------------- | ---------------------------------------------------- |
Expand All @@ -144,7 +253,7 @@ const identify = dedupe(({ cookies }) => {

Note: `dedupe` is not available in Pages Router.

## Flags Explorer Setup
## Flags Explorer setup

### Next.js (App Router)

Expand All @@ -158,7 +267,7 @@ export const GET = createFlagsDiscoveryEndpoint(async () => {
});
```

### With External Provider Data
### With external provider data

```ts
import { getProviderData, createFlagsDiscoveryEndpoint } from 'flags/next';
Expand Down Expand Up @@ -198,7 +307,7 @@ node -e "console.log(crypto.randomBytes(32).toString('base64url'))"

Store as `FLAGS_SECRET` env var. On Vercel: `vc env add FLAGS_SECRET` then `vc env pull`.

## Precompute Pattern (Overview)
## Precompute pattern

Use precompute to keep pages static while using feature flags. Middleware evaluates flags and encodes results into the URL via rewrite. The page reads precomputed values instead of re-evaluating.

Expand All @@ -212,7 +321,7 @@ For full implementation details, see framework-specific references:
- **Next.js**: See [references/nextjs.md](references/nextjs.md) — covers proxy middleware, precompute setup, ISR, generatePermutations, multiple groups
- **SvelteKit**: See [references/sveltekit.md](references/sveltekit.md) — covers reroute hook, middleware, precompute setup, ISR, prerendering

## Custom Adapters
## Custom adapters

Create an adapter factory returning an object with `origin` and `decide`:

Expand All @@ -234,7 +343,7 @@ export function createMyAdapter(/* options */) {
}
```

## Encryption Functions
## Encryption functions

For keeping flag data confidential in the browser (used by Flags Explorer):

Expand All @@ -259,7 +368,7 @@ async function ConfidentialFlags({ values }) {
}
```

## React Components
## React components

```tsx
import { FlagValues, FlagDefinitions } from 'flags/react';
Expand Down
71 changes: 64 additions & 7 deletions skills/flags-sdk/references/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,25 +107,82 @@ export const exampleFlag = flag({
});
```

### CLI
### `vercel flags` CLI

Manage Vercel Flags from the terminal with `vercel flags`. Requires the [Vercel CLI](https://vercel.com/docs/cli) (`pnpm i -g vercel`) and a linked project.
Manage Vercel Flags from the terminal. Requires the [Vercel CLI](https://vercel.com/docs/cli) (`pnpm i -g vercel`) and a linked project (`vercel link`).

Available subcommands: `list`, `add`, `inspect`, `enable`, `disable`, `archive`, `rm`, `sdk-keys`.
#### Subcommands

| Subcommand | Description |
| ------------ | ----------------------------------------------------- |
| `list` | List all flags in the project |
| `add` | Create a new flag |
| `inspect` | Show details, status, and targeting rules of a flag |
| `enable` | Enable a boolean flag for a specific environment |
| `disable` | Disable a boolean flag for a specific environment |
| `archive` | Archive a flag (required before deleting) |
| `rm` | Delete an archived flag |
| `sdk-keys` | Manage SDK keys (subcommands: `ls`, `add`, `rm`) |

#### Create and toggle a flag

```bash
# Create a boolean flag with a description
vercel flags add my-feature --kind boolean --description "New onboarding flow"

# Enable in development first
vercel flags enable my-feature --environment development

# Promote to production
vercel flags enable my-feature --environment production

# Disable in production
vercel flags disable my-feature --environment production
```

`enable` and `disable` only work with boolean flags. For other flag types, configure values in the Vercel dashboard.

#### Inspect and list flags

```bash
# Show details of a specific flag (status, environments, targeting rules)
vercel flags inspect my-feature

# List all flags in the project
vercel flags list
```

#### Archive and delete a flag

A flag must be archived before it can be deleted:

```bash
vercel flags archive my-feature
vercel flags rm my-feature
```

#### Manage SDK keys

SDK keys connect your application to Vercel Flags. The `FLAGS` environment variable contains an SDK key.

```bash
# List SDK keys for the project
vercel flags sdk-keys ls

# Create a new SDK key
vercel flags sdk-keys add

# Remove an SDK key
vercel flags sdk-keys rm <sdk-key-id>
```

`enable` / `disable` only work with boolean flags. A flag must be archived before it can be deleted.
These examples cover common flag operations, but the CLI supports additional commands and options not listed here. For the full `vercel flags` reference and other Vercel CLI commands, install the `vercel-cli` skill:

Full CLI reference: https://vercel.com/docs/cli/flags
```bash
npx skills add https://github.com/vercel/vercel --skill vercel-cli
```

> For broader Vercel CLI usage, install the `vercel-cli` skill:
> `npx skills add https://github.com/vercel/vercel --skill vercel-cli`
Full CLI reference: https://vercel.com/docs/cli/flags

---

Expand Down
Loading