4 min read

Feature Flags pattern

Architectural patterns for working with feature flags
Table of Contents

The flags pattern and precomputed flags pattern exported from @vercel/flags/next are experimental. We are still actively researching and have further iterations planned. These exports are not covered by semantic versioning as indicated by the unstable_ prefix.

Feature flags enable developers to control the rollout of features with precision, allowing for safer deployments and testing in production environments. These flags can be implemented on either the client-side or server-side, each with its distinct implications.

When feature flags are loaded on the client-side, they can introduce visual disruptions such as Layout Shift and jank. This occurs because the client must wait for the flags to load before it can correctly render the page, leading to two less-than-ideal scenarios:

  • Anticipating the flag's value: If the guess is incorrect, the user experiences jank and layout shifts
  • Delaying rendering: Showing a loading state until the flag is loaded delays the user's access to the content

Both approaches detract from the user experience, underscoring the limitations of client-side feature flags.

Server-side loading of feature flags resolves these issues by ensuring that the page is fully prepared with the correct configurations before reaching the user. For static content, such as marketing pages, Edge Middleware can assess feature flags to manage the routing between different page versions, keeping the core page static. While this method adds complexity when managing multiple flags, it enhances performance by eliminating the unpredictability of client-side loading.

At Vercel, we have developed a pattern for the implementation of feature flags:

  • Flags Pattern – Direct evaluation in the dynamic, server-side parts of the application, enhancing immediate adaptability
  • Precomputed Flags Pattern – Evaluation and decision-making occur within middleware, with the results passed down to dynamic components

The Flags Pattern is currently only supported in Next.js App Router. See more in the @vercel/flags/next reference.

The Flags pattern is tailored for applications where dynamic server-side rendering is prevalent. Feature flags are defined and evaluated directly within the server function generating the page content. This method ensures that the feature flags do not interfere with the rendering process, maintaining the application's performance and user experience. Key components of a flag include:

  • key - A unique identifier for the flag
  • origin – The source or context of the flag
  • description – A brief explanation of what the flag controls
  • options: An array consisting of objects with a value and an optional label

A flag may resolve to a value not declared in options, as options are optional.

For each flag, you must implement a decide function that determines its value based on the current request. This function is designed to ensure consistency, offering the same output for identical requests, which is crucial for maintaining stable and predictable application behavior.

Note that not accepting any arguments when calling feature flags does not imply the flag needs to have the same state for all visitors. Instead, the feature flag may derive values from the given request within the decide function and make decisions based on that.

The Precomputed Flags Pattern allows you to define feature flags in code while keeping pages static. The feature flag is evaluated in Edge Middleware. This pattern is currently only supported in Next.js App Router. See more in the@vercel/flags/next reference.

This pattern allows for the precomputation of flags within middleware, thereby determining the appropriate static page version to display ahead of time. It effectively eliminates the inconsistencies typically associated with client-side flag evaluations and is particularly advantageous for pages hosting multiple experiments or feature flags.

Precomputed Flags allow using feature flags in applications while keeping pages static.

In this experimental pattern, the following components are involved:

  • Feature flags are evaluated within Edge Middleware
  • Edge Middleware rewrites incoming requests to serve a static page with the computed combination of feature flags
  • The static page served can either be prerendered at build time or at request time using ISR
    • Prerendering all combinations of all feature flags at build time suffers from combinatorial explosion. It's usually recommended to use ISR

Precomputed flags are implemented in a similar way to the Flags Pattern, with the following additional considerations:

  • A precomputed flag may resolve to a value not declared in options, but this may worsen performance
  • A precomputed flag may not resolve with large values, as the value needs to be transported from Edge Middleware to Functions.
Last updated on June 21, 2024