Flags SDK

repository·main·Indexed 20 days ago

https://github.com/vercel/flags

A monorepo for the Flags SDK providing a framework for dynamic server-side feature flagging. It includes multiple backend adapters such as PostHog, GrowthBook, Hypertune, LaunchDarkly, and a Global Config adapter, as well as integration with the Flags Explorer for managing overrides and variations.

Tokens
98.8K
Snippets
354
Records
413
Agent score
69%

What's inside vercel-flags

  1. What is the Flags SDK?

    main

    The Flags SDK (flags npm package) is a feature flags toolkit designed for Next.js and SvelteKit. It allows you to treat feature flags as callable functions, enabling server-side evaluation to prevent layout shifts and maintain page performance. It uses an adapter pattern to connect to various providers, including Vercel Flags (the first-party provider), Statsig, LaunchDarkly, and others.

    import { flag } from 'flags/next';
    
    export const exampleFlag = flag({
      key: 'example-flag',
      decide() { return false; },
    });
    
    const value = await exampleFlag();
  2. Overview of Geistdocs documentation template

    main

    Geistdocs is a modern documentation template built using Next.js and Fumadocs. It is designed to help developers quickly deploy Vercel documentation sites with a consistent UI and built-in features like AI chat and GitHub Discussions integration.

    Key features include:

    • MDX-powered documentation: Full support for writing docs using MDX components.
    • AI-powered chat: An integrated AI assistant trained on your documentation.
    • GitHub Discussions integration: Enables users to provide feedback directly via GitHub.
    • Advanced search: Fast, fuzzy search capabilities across all documentation.
    • Modern UI: Accessible components built with Radix UI, featuring dark mode and responsive design.
    • Performance: Built on Next.js 16 with App Router and includes built-in RSS feeds.
  3. Choose a provider integration type

    main

    Providers in the Flags SDK ecosystem are categorized by their capabilities:

    • Adapter: Enables flag and experiment evaluation using the Flags SDK.
    • Flags Explorer: Enables the display of flag metadata (such as descriptions) within the Flags Explorer.
    • Marketplace: Providers available via the Vercel Marketplace.
    • Global Config: Enables reading feature flags from a Global Config for low latency.
  4. Implement Partial Prerendering with feature flag variants

    main

    When using Next.js Partial Prerendering, combining it with precomputed flags allows the deployment of multiple static shells. For a single route, the system can generate:

    1. A shell containing the unauthenticated skeleton.
    2. A shell containing the authenticated skeleton.

    This allows marketing pages or landing pages to be served statically without blocking the response on slow auth state resolution, while still providing a seamless transition (streaming the auth state) once it is resolved.

  5. Declare feature flag defaults and context

    main

    When declaring a flag using flag(), you define its defaultValue and how its evaluation context is established via the identify() method. This centralizes the logic for context creation, preventing the need to manually pass user or session data at every call site, which reduces the risk of inconsistent evaluations across the codebase.

    import { flag } from 'flags/next';
    
    export const exampleFlag = flag({
      key: 'example-flag',
      defaultValue: false,
      // Establishes the evaluation context centrally
      identify() {
        return { user: { id: '123' } };
      },
      // Uses the established context to decide the flag value
      decide({ entities }) {
        return entities.user.id === '123';
      },
    });
  6. Manage combinatory explosion in permutations

    main

    Using many feature flags or flags with many possible values leads to an exponential increase in permutations. This can increase build times (if using build-time rendering) or decrease cache hit rates (if using lazy ISR generation).

    To mitigate this, you can manually specify which permutations to generate at build time by passing a second argument to generatePermutations. All other permutations will be generated on demand the first time they are requested.

  7. Integrate feature flag providers with Flags SDK using adapters

    main
    You can integrate any feature flag provider with the Flags SDK by using an adapter. The Flags SDK provides published adapters for common providers, which allows you to evaluate feature flags and experiments through a unified interface. If your provider is not listed, you can implement a custom adapter to connect your in-house solution or unsupported provider to the SDK.
  8. How evaluation context works with identify and decide

    main

    Evaluation context allows you to decouple user identification from feature flag decision-making.

    1. identify: A function that returns an object representing the user or environment (the "entities").
    2. decide: A function that receives those entities as an argument and returns the flag's value (e.g., true or false).

    This pattern allows you to segment features based on any criteria, such as user IDs, roles, or device types.

    import { flag } from 'flags/next';
    
    export const exampleFlag = flag<boolean>({
      key: 'identify-example-flag',
      identify() {
        // Returns the entities used for evaluation
        return { user: { id: 'user1' } };
      },
      decide({ entities }) {
        // Uses the entities to make a decision
        return entities?.user?.id === 'user1';
      },
    });
  9. Understand PostHog evaluation modes

    main

    The PostHog adapter supports two evaluation modes:

    Remote Evaluation (Default)

    Triggered by: Providing POSTHOG_PROJECT_API_KEY and POSTHOG_HOST.

    • How it works: Makes a network request to PostHog for every flag evaluation.
    • Pros/Cons: Higher latency and per-request billing; allows PostHog to look up additional user properties from its database.

    Local Evaluation

    Triggered by: Providing POSTHOG_SECRET_KEY (phs_...).

    • How it works: Uses posthog-node to periodically fetch flag definitions in the background (default every 30s) and evaluates them in-process.
    • Pros/Cons: Lower latency and lower cost for long-running processes (billed as 10 requests per poll).
    • Warning: Not recommended for short-lived compute (like serverless functions) as the poller cannot amortize costs.
    • Note: You are responsible for providing all properties required by flag release conditions locally.
  10. Configure Evaluation Context with identify

    main

    To evaluate flags based on user identity (e.g., user IDs from cookies), use the identify property in the flag configuration.

    identify is a function that receives normalized headers and cookies and returns an object of Entities. These entities are then passed to the decide function. You can use dedupe to ensure the identify logic runs only once per request.

    import { flag, dedupe } from 'flags/next';
    import type { ReadonlyRequestCookies } from 'flags';
    
    interface Entities {
      user?: { id: string };
    }
    
    const identify = dedupe(
      ({ cookies }: { cookies: ReadonlyRequestCookies }): Entities => {
        const userId = cookies.get('user-id')?.value;
        return { user: userId ? { id: userId } : undefined };
      },
    );
    
    export const myFlag = flag<boolean, Entities>({
      key: 'my-flag',
      identify,
      decide({ entities }) {
        return entities?.user?.id === 'user1';
      },
    });
  11. Understand feature flag evaluation requirements

    main

    Feature flag evaluation is the process of determining a flag's value based on two inputs:

    1. Definition: The rules for evaluation (e.g., which users get a feature), typically loaded from a feature flag provider.
    2. Evaluation Context: Data about the specific user or entity being evaluated.

    The relationship is expressed as: evaluate(definition, evaluation context) = value

    Flags that are globally on or off do not require an evaluation context, but flags targeting specific user segments do.