Docs/Guides/

Trunk-Based Development

Ship incomplete features to main safely using feature flags

Trunk-based development is a branching strategy where all developers commit to a single branch (main or trunk). Feature flags make this practical by letting you merge incomplete work without exposing it to users.

The problem with long-lived branches

Long-lived feature branches cause:

  • Merge conflicts — the longer a branch lives, the harder it is to merge
  • Integration risk — bugs are discovered late when branches finally merge
  • Slow feedback loops — code reviews are large and hard to review
  • Deployment bottlenecks — releases are blocked by unfinished features

How flags solve this

With feature flags, you can:

  1. Merge to main daily — wrap incomplete work behind a flag
  2. Deploy continuously — the flag is off, so users don't see unfinished features
  3. Integrate early — catch conflicts and bugs as they happen
  4. Release independently — enable the flag when the feature is ready
Traditional:                          With flags:

main ──────────────────────           main ─── deploy ─── deploy ─── deploy
  \                       /              ↑        ↑         ↑         ↑
   feature-branch (weeks) /             commit   commit    commit    commit
    \_____________________/             (flagged) (flagged) (flagged) (flag ON)

Workflow

Step 1: Create the flag first

Before writing any code, create a boolean flag in the dashboard:

  • Key: new-billing-page
  • Type: Boolean
  • State: Disabled in all environments

Step 2: Write code behind the flag

if (client.isEnabled('new-billing-page')) {
  return renderNewBillingPage()
}
return renderCurrentBillingPage()
import { Feature } from '@flagpool/react'

function BillingPage() {
  return (
    <Feature flag="new-billing-page" fallback={<CurrentBillingPage />}>
      <NewBillingPage />
    </Feature>
  )
}

Step 3: Merge to main daily

Commit and push your work daily. The feature is hidden behind the flag, so it's safe to deploy even if incomplete.

git add .
git commit -m "feat: new billing page - add payment method section (flagged)"
git push origin main

Step 4: Enable when ready

When the feature is complete and tested:

  1. Enable the flag in Development — test locally
  2. Enable in Staging — validate with QA
  3. Enable in Production — roll out (start with a low percentage if you want)

Step 5: Clean up

Once the feature is fully shipped:

  1. Remove the flag check from code
  2. Delete the old code path
  3. Archive the flag in the dashboard

Handling incomplete UI

When a feature spans multiple components, use the same flag key everywhere:

// Navigation
<Feature flag="new-billing-page">
  <NavLink to="/billing-v2">Billing</NavLink>
</Feature>

// Routes
<Feature flag="new-billing-page" fallback={<OldBillingRoute />}>
  <NewBillingRoute />
</Feature>

// API layer
if (client.isEnabled('new-billing-page')) {
  return fetchFromNewBillingAPI()
}
return fetchFromLegacyAPI()

Using one flag for the entire feature ensures everything toggles together.

Best practices

Use prefixes for work-in-progress flags

wip_new-billing-page
wip_redesigned-settings

This makes it easy to identify flags that exist only for development purposes and should eventually be cleaned up.

Keep flag code minimal

The flag should control which code path runs, not contain complex branching logic:

// Good — clean separation
if (client.isEnabled('new-billing')) {
  return <NewBilling />
}
return <OldBilling />

// Bad — tangled logic
return (
  <div>
    {client.isEnabled('new-billing') ? <NewHeader /> : <OldHeader />}
    <SharedContent />
    {client.isEnabled('new-billing') ? <NewFooter /> : <OldFooter />}
    {client.isEnabled('new-billing') && <NewSidebar />}
  </div>
)

Set a cleanup deadline

When creating a flag, agree on when it should be removed. Flagpool's stale flag detection (Starter plan and above) helps identify flags that have been on for too long.

Next steps

Start Managing Feature Flags Today

Join teams who trust Flagpool to deliver features safely and efficiently.

No credit card required • Cancel anytime