Introduction to Vercel Feature Flags to Accelerate Trunk-Based Development - How to Use Flags SDK, Toolbar, and Edge Config

Introduction to Vercel Feature Flags to Accelerate Trunk-Based Development - How to Use Flags SDK, Toolbar, and Edge Config

2026.01.17

This page has been translated by machine translation. View original

Hello, this is Toshima.

In this article, I'll explain the appeal and specific usage methods of Vercel's Feature Flags, which are useful for implementing trunk-based development.

Introduction

Trunk-based development is a development strategy where all developers frequently commit to a single branch, using short-term feature branches.
This approach minimizes merge conflicts and enables continuous integration (CI). However, to successfully implement trunk-based development, a mechanism that separates deployment to production environments from feature activation is essential.

This is where Vercel's Feature Flags come into play. Vercel's Feature Flags are deeply integrated into trunk-based development workflow and accelerate the entire frontend development lifecycle.

In this article, I'll introduce the Feature Flags-related functions provided by Vercel and explain how to use them in trunk-based development.
Specifically, I'll cover the following three features:

Component Main Role Characteristics
Flags SDK Flag evaluation within applications Open-source, optimized for Next.js/SvelteKit
Vercel Toolbar Flag manipulation during development and QA Override flag values directly from the browser to confirm behavior in real-time
Edge Config Global configuration data store Ultra-low latency data reading, suitable for A/B testing and redirects

By combining these tools, you can implement release strategies such as personalization based on user attributes and gradual feature rollout, not just simple ON/OFF functionality.

About Flags SDK

@vercel/flags is a library for integrating feature flags into Next.js and SvelteKit applications. It's based on server-side evaluation and designed to minimize performance impact.

https://flags-sdk.dev/

Examples of defining and using flags

Defining flags in a common file like lib/flags.ts makes them easier to manage.
You can also utilize request information (headers, cookies) in the decide function.

lib/flags.ts

import { flag } from 'flags/next'

// Simple boolean example
export const showNewFeature = flag<boolean>({
  key: 'new-feature',
  decide: () => process.env.ENABLE_NEW_FEATURE === 'true',
})

// Example using request headers (regional information)
type GDPRBannerEntities = {
  country: string
}

export const enableGDPRBanner = flag<boolean, GDPRBannerEntities>({
  key: 'gdpr-banner',
  identify({ headers }): GDPRBannerEntities {
    return {
      country: headers.get('x-vercel-ip-country') || 'US',
    }
  },
  decide({ entities }) {
    const euCountries = ['DE', 'FR', 'ES', 'IT'] // Add other EU member countries
    return euCountries.includes(entities.country)
  },
})

// Example that changes based on cookies (user tier)
export type BannerTheme = 'default' | 'premium' | 'sale'

type HeroBannerEntities = {
  userTier: string | undefined
}

export const heroBannerTheme = flag<BannerTheme, HeroBannerEntities>({
  key: 'hero-banner-theme',
  identify({ cookies }): HeroBannerEntities {
    return {
      userTier: cookies.get('user_tier')?.value,
    }
  },
  decide({ entities }) {
    if (entities.userTier === 'premium') {
      return 'premium'
    }
    if (process.env.IS_SALE_PERIOD === 'true') {
      return 'sale'
    }
    return 'default'
  },
})

For more practical content such as Dedupe and Precompute, please check each document.

Flag evaluation in components

Evaluate defined flags in server components or API routes.

import { showNewFeature, enableGDPRBanner, heroBannerTheme } from '@/lib/flags'
import { GDPRBanner, NewFeatureComponent, HeroBanner } from '@/components'

export default async function HomePage() {
  // Evaluate multiple flags in parallel
  const [isNewFeatureEnabled, isGDPRBannerEnabled, bannerTheme] = await Promise.all([
    showNewFeature(),
    enableGDPRBanner(),
    heroBannerTheme(),
  ])

  return (
    <main>
      <HeroBanner theme={bannerTheme} />
      {isNewFeatureEnabled && <NewFeatureComponent />}
      {isGDPRBannerEnabled && <GDPRBanner />}
    </main>
  )
}

Next, I'll introduce Vercel Toolbar, which allows you to easily toggle defined flags during development.

About Vercel Toolbar

By implementing Vercel Toolbar, you can override feature flag values directly from the browser during development or in preview environments to check behavior.
This allows you to test various scenarios without deployment.

About enabling the Toolbar

The configuration details are as described in the documentation:
https://vercel.com/docs/vercel-toolbar/in-production-and-localhost

The Toolbar appears in preview environments (verification environments created from branches or PRs connected to Vercel).
Arc-2025-12-18 002309

From here, press Flags Explorer to make some changes.
Let's try turning on "summer-sale" and clicking Apply:
Arc-2025-12-18 002311

The Summer Sale banner is now displayed:
Arc-2025-12-18 002313

The cart page now includes a Summer discount:
Arc-2025-12-18 002315

This way, you can check UI changes and behavior without deployment.

Sample code using flags is publicly available; for details, please check the repository.

So far we've been managing flags with environment variables, but this requires deployment each time flag values change. The next section introduces Edge Config, which allows dynamic flag value changes without deployment.

About Edge Config

In the examples so far, we've managed flags with environment variables. However, this requires deployment every time flag values change.
With Edge Config, you can change flag values from the Vercel dashboard without deployment, and read data with ultra-low latency by placing it on Vercel's global edge network. It's suitable for storing data that is frequently read but infrequently updated.

Setting up Edge Config

Create Edge Config in the Vercel dashboard and proceed with configuration.

https://vercel.com/docs/edge-config/get-started

Flag definition using Edge Config

Below is an example of a simple flag definition using Edge Config. Values stored in Edge Config are retrieved via an adapter and evaluated in the decide function.

lib/flags.ts

import { flag } from 'flags/next'
import { edgeConfigAdapter } from '@flags-sdk/edge-config'

// Get boolean values from Edge Config
export const showBetaDashboard = flag<boolean>({
  key: 'beta-dashboard',
  adapter: edgeConfigAdapter(),
  decide({ value }) {
    return value ?? false
  },
})

// Pattern for directly storing 'A' or 'B' in Edge Config
// Show the same variant to all users (for gradual rollout)
export const checkoutVariant = flag<'A' | 'B'>({
  key: 'checkout-variant',
  adapter: edgeConfigAdapter(),
  decide({ value }) {
    return value === 'A' || value === 'B' ? value : 'A'
  },
})

Utilizing Edge Middleware

The true value of Edge Config is demonstrated when combined with Middleware.
You can rewrite requests or redirect them at the edge before they reach the origin server.

In the context of Feature Flags, combining Edge Config with Middleware allows dynamic control of maintenance mode switching or access control from specific IP addresses.
Below is a simplified example. In production use, additional considerations such as returning 503 status codes and detailed logging would be necessary.

middleware.ts

import { NextResponse, type NextRequest } from 'next/server'
import { get } from '@vercel/edge-config'

export const config = {
  matcher: [
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
}

export async function middleware(request: NextRequest) {
  const { nextUrl, ip } = request

  try {
    const [isMaintenance, blockedIps] = await Promise.all([
      get<boolean>('isMaintenance').then(v => v ?? false),
      get<string[]>('blockedIps').then(v => v ?? []),
    ])

    // IP blocking
    if (ip && blockedIps.includes(ip)) {
      return new NextResponse('Forbidden', { status: 403 })
    }

    // Maintenance mode
    const isMaintenancePath =
      nextUrl.pathname === '/maintenance' ||
      nextUrl.pathname.startsWith('/maintenance/')

    if (isMaintenance && !isMaintenancePath) {
      return NextResponse.rewrite(new URL('/maintenance', request.url))
    }

    return NextResponse.next()
  } catch (error) {
    console.error('Edge Config error:', error)
    return NextResponse.next()
  }
}

Practical Tips

Here are some tips for using Feature Flags in production.

Flag naming conventions

Deciding on consistent naming conventions for your team makes management easier.

Pattern Example Use case
enable-* enable-dark-mode Feature ON/OFF
show-* show-beta-banner UI element display control
use-* use-new-checkout Implementation switching

Removing unnecessary flags

Flags can easily become technical debt, so it's important to regularly take inventory.

  • Remove flag checks from code once they've been fully rolled out to all users
  • Delete settings from Edge Config and the Vercel dashboard
  • Recording a "scheduled removal date" when creating flags is effective for preventing removal oversights

Production usage considerations

  • Always set default values: Set default values for flags to prepare for Edge Config connection issues
  • Gradual rollout: Deploy new features gradually, starting with a subset of users, and only roll out to everyone after confirming there are no issues
  • Set up monitoring: Monitor for changes in error rates or performance before and after flag switches. This example code has minimal logging for simplicity, but for production use, consider detailed log design including paths, IPs, timestamps, etc.

Summary

In this article, I introduced three Feature Flags-related functions provided by Vercel:

  • Flags SDK: A library for defining and evaluating flags within applications
  • Vercel Toolbar: A tool for manipulating flags from the browser during development and QA
  • Edge Config: A data store for reading flag values with ultra-low latency

By combining these, you can separate code deployment from feature release, implementing safe and flexible release strategies.
If you're practicing trunk-based development or considering its implementation, please try Vercel's Feature Flags.

Share this article

FacebookHatena blogX

Related articles