# Trunk-based development

> Everyone merges small changes to main at least daily and hides unfinished work behind flags.

Concept · Merging & history · https://levelcode.org/concepts/trunk-based-development

In **trunk-based development**, everyone integrates into one shared branch, the trunk (usually `main`), **at least once a day**. Branches, if you use them at all, live for hours or a day or two, not weeks. `main` is always releasable.

```text
main  ●──●──●──●──●──●──●──●──●──   (many small merges per day)
       \─●─/  \●/  \─●─/            (short-lived branches / PRs)
```

The opposite is long-lived feature branches merged at the end of a project, or GitFlow-style `develop` and release branches. Those defer integration, and the pain grows the longer you wait: big conflicts, surprise interactions, "merge week."

## What makes it work

- **Small changes.** Each PR does one thing and is reviewable in minutes. Large features land as a series of safe steps.
- **Fast CI on every change.** If `main` is red, fixing it comes before any new work.
- **Feature flags.** Unfinished code merges to `main` *switched off*:

```go
if flags.Enabled(ctx, "new-checkout", user) {
	return newCheckout(ctx, cart)
}
return legacyCheckout(ctx, cart)
```

  This separates **deploying** code from **releasing** a feature. You can turn the feature on for staff, then 5% of users, then everyone, and turn it off instantly if something goes wrong. See [deployment strategies](https://levelcode.org/concepts/deployment-strategies). The same switch serves [graceful degradation](https://levelcode.org/concepts/graceful-degradation).
- **Branch by abstraction for big rewrites:** put an interface in front of the old implementation, build the new one behind it, switch over, then delete the old one. Every step merges to `main`.

## Trade-offs

- **It requires discipline and automation.** Without good tests and CI, integrating often only spreads breakage faster.
- **Flags are debt.** Remove each flag once its feature is fully released, or the code fills up with branches nobody understands.
- **Not every context fits.** Open-source projects with outside contributors, or products that ship several supported versions, may need longer-lived branches.

## Where GitHub flow fits

GitHub flow (branch → PR → review → merge to `main` → deploy) is trunk-based development when the branches are short-lived. The rule that makes it trunk-based is how long branches live, not whether you use PRs.

Short branches also mean fewer [merge conflicts](https://levelcode.org/concepts/three-way-merge) and less need to [rebase](https://levelcode.org/concepts/merge-vs-rebase). The [team workflows lesson](https://levelcode.org/roadmaps/git/workflows) compares the options.
