Feature flag PRs demand more code review skill than most, because the risk isn't just in the new code path. It's in the interaction between two live paths, the flag's default state, every call site across the codebase, and the cleanup plan that almost never makes it into the description. A thorough review takes thirty to sixty minutes and leaves you confident the flag can be toggled safely in any environment.

If you've approved a flag PR only to see a silent production enable, a partial rollout with split data, or a security check that lived inside the flag block, this guide is for you. The steps below follow the order you'd work through a real diff.

What you need before you start

Gather three things before opening the diff: the full file diff, the flag configuration file or dashboard, and every test file that references the flag.

Without the flag config, you can't verify the default state, the targeting rules, or whether a stale flag is being retired or left in place. If the team uses a flag management tool such as LaunchDarkly, Unleash, or Flagsmith, open it alongside the PR and cross-reference flag names exactly as they appear in both places. A single character difference in a flag key means the code and the platform are reading different flags.

Also check whether the stack wraps the flag client in a custom abstraction. A wrapper can hide coercion bugs, such as a string "false" being cast to the boolean true, that the raw SDK would surface immediately.

1. Confirm the flag's default state matches the deployment plan

The flag's default value is your safety net if the flag service is unreachable at runtime. Most SDKs fall back to the in-code default, so that value decides what users see during an outage.

A flag that defaults to true in production but was authored expecting false will silently enable unfinished work the moment the deploy lands. Check the default in code and in the flag platform. They should agree. If the platform overrides the code default, confirm that override is documented and intentional, not left over from a previous experiment.

Ask in the review what the correct fallback is for each environment. Development, staging, and production often need different answers.

2. Read both code paths, not just the new one

2a. Verify the old path still works

The existing code path must function correctly when the flag is off, because most users will stay on it until the rollout completes. Reviewers consistently over-index on the new feature and miss regressions in the control path. Trace through the false branch as carefully as the true branch, and confirm its tests still pass with no modifications.

2b. Check that the two paths share no mutable state

If both branches write to the same variable, cache key, or database row without coordination, a partial rollout will produce inconsistent data across users. Look for shared side effects: analytics events fired in one branch but not the other, session tokens mutated by the new path, or queue messages published only when the flag is on. Any of these can cause subtle, hard-to-reproduce bugs during a gradual rollout when a single user's requests hit different servers with different flag evaluations.

Building the habit of reading both branches is one of the code review skills that compound over a career rather than plateau early.

3. Check every call site, not just the primary one

A flag introduced in one component is often read in several places, and a PR that only wraps one call site leaves the others behaving inconsistently.

Search the diff for the flag's string key. Then search the full repository for that same key. Any call site not in the diff is a gap the author may not have noticed. Pay particular attention to API routes, middleware, and background jobs. These are less visible than UI components but carry more risk when they branch on a stale or misread flag value.

If the PR adds a new call site to an existing flag, confirm the flag's lifecycle. A flag that's scheduled for removal shouldn't be getting new call sites. That's a signal the removal plan has slipped and nobody has noticed yet.

4. Verify the security boundary the flag creates

4a. Confirm the flag is not the only access control

A feature flag controls visibility, not authorization. If the new code path exposes an endpoint, a data field, or an admin action, server-side permission checks must exist independently of the flag. A user who discovers the flag key or manipulates client state should hit a permissions wall, not a live feature.

Look for auth checks inside the flagged block, not just around it. A check placed outside the flag block may not apply once the flag is permanently removed, which creates a silent regression at cleanup time. This pattern comes up frequently in PRs that change how sessions and tokens are handled, and the same discipline applies here: reviewing pull requests that change session and token handling covers the auth-check placement question in depth.

4b. Check what the flag exposes in the client bundle

In React, Next.js, Vue, and similar frameworks, flag evaluation often happens client-side, which means both branches can ship in the JavaScript bundle regardless of which one renders. If the new path contains unreleased UI copy, internal route names, or API endpoints not yet hardened, ask whether those strings need to be excluded from the bundle until the flag is fully on. A determined user can read your bundle before you've flipped the switch.

5. Confirm the cleanup plan is in the PR

A PR that introduces a flag without a removal plan is creating future debt, and the review is the right moment to surface it. The PR description or a linked ticket should name the condition for full rollout, the condition for rollback, and the sprint or date by which the flag will be removed.

Check whether the flag name follows the team's naming convention. A consistent pattern such as release/payments-v2 or experiment/checkout-redesign makes bulk audits and cleanup scripts feasible. An ad-hoc name makes the flag invisible to anyone who didn't write it.

If the codebase already has flags older than the agreed lifespan, note it in the review. Stale flags are a maintenance risk and occasionally a security one, particularly when they gate deprecated auth flows or legacy data formats. Raising it in the current review is more useful than filing a separate ticket that nobody prioritises.

If you find yourself unsure how to phrase any of these observations as a comment, what makes a code review comment actionable instead of just correct gives practical patterns for turning a valid concern into something the author can act on.

Frequently asked questions

Should the flag evaluation logic itself have unit tests?

Yes. Tests that explicitly assert behaviour when the flag is true and when it's false prevent future refactors from collapsing both paths into one. If you see a PR that adds flag-dependent logic with no corresponding test variation, ask for it.

What if the PR removes a flag rather than adding one?

A removal PR deserves the same scrutiny as an introduction. Confirm the removed branch is the one being deleted, not the one being kept. Check that all call sites are gone, not just the primary one. Verify that any permission checks from inside the flagged block have been preserved in the surviving code.

How do I review a flag PR in a codebase I don't know well?

Start with the flag config to understand intent, then follow the string key through the repository rather than reading the diff top to bottom. That order surfaces every call site before you evaluate any individual one. The mechanics of a GitHub code review covers navigation strategies for unfamiliar codebases in more detail.

Practice graded pull request reviews on real code at Goodcatch, no account required.