惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Jina AI
Jina AI
博客园 - 司徒正美
大猫的无限游戏
大猫的无限游戏
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
博客园 - 聂微东
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
美团技术团队
腾讯CDC
博客园 - Franky
MyScale Blog
MyScale Blog
人人都是产品经理
人人都是产品经理
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
aimingoo的专栏
aimingoo的专栏
博客园_首页
V
V2EX
Martin Fowler
Martin Fowler
T
The Blog of Author Tim Ferriss

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
How to use feature flags in JavaScript and TypeScript
Flaggy · 2026-05-20 · via DEV Community

A practical guide to implementing feature flags in JS/TS: what they are, when to use them, and how to avoid the traps that make them painful to manage.

Feature flags are a conditional: if (flagEnabled) { show new thing } else { show old thing }. That’s the entire concept. The value comes from where the condition is evaluated and who controls it — not the developer at deploy time, but a dashboard at runtime.

This guide covers the core patterns, when each one applies, and what separates a well-managed flag from one that quietly rots in your codebase.

The basic pattern

A feature flag SDK gives you a function. You call it with a flag key, optionally a user context, and it returns a boolean (or a variant, for multivariate flags).

import { flaggy } from '@flaggy.io/sdk-js';

const client = flaggy({ apiKey: process.env.FLAGGY_API_KEY });
await client.initialize();

if (client.isEnabled('release-checkout-flow', { key: user.id })) {
  return <NewCheckout />;
}
return <LegacyCheckout />;

Enter fullscreen mode Exit fullscreen mode

The SDK downloads your ruleset on initialization and evaluates locally. No network call happens at the point of evaluation — it’s a dictionary lookup against rules in memory. This is why MAU-based pricing from some vendors doesn’t make technical sense: the vendor’s infrastructure isn’t involved when a flag evaluates.

When to use a feature flag

Release control is the most common case. You merge a half-finished feature to main behind a flag, deploy continuously, and flip the flag when it’s ready. No long-lived feature branches, no merge conflicts.

Percentage rollouts let you ship to 5% of users, watch your error rate, and expand if it looks clean. This is a canary deployment without the infrastructure complexity of actually routing traffic.

User targeting lets you ship to internal users, beta testers, or a specific customer segment first. You define a segment in the dashboard — “users where plan = enterprise” — and enable the flag for that segment.

Kill switches are flags you never intend to remove. A circuit breaker on a third-party integration, a way to disable a feature if it’s causing support volume. Having this in a dashboard is faster than a deploy.

The initialization pattern

Initialize the SDK once at app startup and share the client. Don’t initialize per-request or per-component — it defeats the local evaluation model.

// flaggy.ts — initialize once, export everywhere
import { flaggy } from '@flaggy.io/sdk-js';

export const flags = flaggy({
  apiKey: process.env.FLAGGY_API_KEY!,
});

await flags.initialize();
// any component or module
import { flags } from './flaggy';

const showFeature = flags.isEnabled('my-feature', { key: currentUser.id });

Enter fullscreen mode Exit fullscreen mode

Targeting rules

Most SDKs let you pass a context object — any key/value pairs you want to use for targeting. The dashboard lets you define rules against those attributes without a code change.

Common context attributes:

flags.isEnabled('experiment-dark-mode', {
  key: user.id,
  email: user.email,
  plan: user.plan,           // target by billing tier
  accountAge: daysSinceSignup,
  country: user.countryCode,
});

Enter fullscreen mode Exit fullscreen mode

You define the rule once in the dashboard: “users where plan = team AND accountAge > 30”. No deploy required to change targeting.

The cleanup problem

The real cost of feature flags isn’t evaluating them — it’s the ones you forget to remove. A codebase with 200 permanent flags is harder to reason about than one with 20.

A few habits that help:

Add a ticket at flag creation. When you create a flag, immediately create a ticket to remove it after the rollout is done. The flag has a lifespan of “rollout + one release cycle.”

Name flags by lifecycle prefix. Use a prefix that encodes intent: release-new-dashboard, experiment-checkout-button, kill-switch-payment-provider, ops-cache-ttl. It makes lifespan visible at a glance — you can immediately separate flags that need cleanup from ones that are permanent.

Review old flags quarterly. Pull a list of flags that haven’t changed in 90 days. Most of them are either fully rolled out (safe to remove) or forgotten experiments.

Server-side vs client-side evaluation

Some teams evaluate flags server-side to avoid any flag state being visible in the client bundle. The tradeoff:

Client-side: zero latency at evaluation, no server dependency, flag rules are technically visible in the bundle (usually fine for most use cases)
Server-side: rules stay private, adds one lookup per request (fast if in-memory, latency concern if remote)
For most product flags — rollouts, A/B tests, kill switches — client-side evaluation is fine. For flags that gate access control or pricing, server-side is worth the overhead.

What to look for in a flag platform

You need: a dashboard to manage flags without a code change, targeting rules, audit history (who changed what and when), and an SDK that evaluates locally.

What you don’t need to pay for: MAU metering. Modern SDKs evaluate client-side. The vendor’s servers aren’t involved in evaluations — if you’re paying per-MAU, you’re paying for a proxy metric that doesn’t reflect actual vendor cost.

Flaggy’s Team plan is $99/month flat — unlimited seats, no MAU fees, full flag analytics and audit log included.