TL;DR:

  • Trunk-based development reduces merge conflicts and keeps main deployable; Gitflow is more appropriate for versioned software with defined release cycles
  • Feature flags are the enabler that makes trunk-based development work for features that take weeks to build
  • Most web teams shipping continuously should default to trunk-based; teams shipping versioned software (SDKs, mobile apps, firmware) have genuine reasons to consider Gitflow

Gitflow vs trunk-based development is a strategy question that shapes how your team works every day. Get it wrong and you’ll spend hours resolving merge conflicts, fighting stale branches, or struggling to release a hotfix while a half-finished feature is partially merged. Get it right and release becomes a non-event.

How Gitflow Works

Gitflow defines a set of long-lived branches with specific purposes: main (production), develop (integration), feature branches, release branches, and hotfix branches. A feature starts as a branch off develop, is merged back into develop when complete, gets bundled with other features into a release branch for testing, and is merged into both main and develop when released.

It’s structured and clear. Every branch has a purpose. A hotfix creates a branch off main, gets merged into both main and develop, and is tagged. The flow is predictable.

The problems emerge at scale and speed. Long-lived feature branches accumulate divergence from develop. The longer a branch lives, the larger the merge becomes. Integration only happens at merge time, which means teams discover conflicts late — after a feature is “done.” Release branches create a holding pattern where code is ready but blocked waiting for other features or release sign-off.

For teams shipping continuously (multiple times per day), Gitflow’s structure becomes overhead rather than guardrails.

How Trunk-Based Development Works

Trunk-based development has one primary rule: every developer integrates their work into main (the “trunk”) at least once per day. Feature branches exist but are short-lived — hours or days, not weeks.

This keeps main in a perpetually deployable state. There’s no integration branch to merge into, no release branch to manage. The latest commit on main is always ready to deploy.

Here’s the thing, though: what do you do with a feature that takes three weeks to build? You can’t merge half a feature.

Feature flags are the answer. You ship the code — wrapped in a flag that’s off by default — and the feature is invisible until the flag is enabled. The code is merged and tested continuously; the feature is revealed only when it’s ready.

// Feature flag pattern
if (featureFlags.isEnabled('new-checkout-flow', user)) {
  return <NewCheckoutFlow />;
}
return <LegacyCheckoutFlow />;

Tools like LaunchDarkly, Flagsmith (open source), and Unleash manage flag state, targeting rules, and gradual rollouts without code deploys.

When Each Approach Fits

Trunk-based development works better for:

  • Web applications with continuous deployment
  • Teams with good test coverage and CI pipelines
  • Small teams (2–8 engineers) where coordination overhead is high relative to team size
  • Any team measuring lead time to production in hours rather than weeks

Gitflow works better for:

  • Versioned software: mobile apps, SDKs, npm packages, firmware
  • Teams that ship defined releases rather than continuous deploys (e.g., enterprise software with customer installation schedules)
  • Open source projects where contributors work asynchronously across many time zones
  • Teams that need to maintain multiple versions simultaneously

The misconception is that trunk-based is always “more advanced” or “more mature.” It’s not. It’s the right model for a specific deployment pattern. If you’re shipping a public npm package and need to maintain v1.x, v2.x, and v3.x simultaneously, Gitflow’s structure exists for good reasons.

Migrating from Gitflow to Trunk-Based

If your team is on Gitflow and shipping continuously, migration is worth pursuing. The practical steps:

Shrink branch lifetimes first. Before changing the branching model, enforce a rule that no feature branch lives longer than three days. This surfaces the real problem: features take too long because they’re too large.

Break down features. Long branches are usually a consequence of large features. Break them into smaller vertical slices that deliver incremental value.

Add feature flags. Before you stop using develop, implement flag infrastructure so work-in-progress can merge safely.

Eliminate develop last. Once branches are short-lived and flags are in place, the develop branch becomes redundant. Remove it.

The migration is behavioural as much as technical. Developers accustomed to long feature branches resist merging incomplete work, even when it’s behind a flag. The cultural shift is the harder part — especially in larger teams where established processes have a lot of momentum.

The Bottom Line

If your team deploys a web application more than once per week, trunk-based development with feature flags will reduce your merge pain and keep main deployable. If you ship versioned software on defined release cycles, Gitflow’s structure provides exactly the guardrails you need. The worst outcome is applying trunk-based discipline to a mobile app release cycle, or forcing Gitflow onto a team deploying fifteen times a day.