Trunk-Based Development
Trunk-Based Development (TBD) is a branching strategy where developers work in short-lived branches (or directly on main) and merge frequently. It's designed for continuous integration and rapid deployment.
Core Principles
- Single source of truth: One main branch (trunk)
- Short-lived branches: Hours to days, not weeks
- Frequent integration: Multiple merges per day
- Always releasable: Trunk is always deployable
main (trunk): ──●──●──●──●──●──●──●──●──●──●──
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
│ │ │ │ │ │ │ │ │ │
branches: ● ● ● ● ● ● ● ● ● ●
(each lives < 1-2 days)
How It Works
Small Changes, Fast Merges
# Create short-lived branch
git checkout main
git pull
git checkout -b add-logout-button
# Make small, focused change
# ... edit files ...
git add .
git commit -m "Add logout button to header"
# Push and create PR
git push -u origin add-logout-button
# Merge same day (after review)
# Then delete branch
Or Commit Directly
Some teams commit directly to main:
git checkout main
git pull
# Make change
git add .
git commit -m "Fix typo in error message"
git push
This requires strong CI and team discipline.
Key Practices
1. Feature Flags
Ship incomplete features behind flags:
// Feature flag in code
if (featureFlags.newCheckout) {
return <NewCheckoutFlow />;
}
return <OldCheckoutFlow />;
Benefits:
- Merge incomplete work
- Gradual rollout
- Easy rollback
- A/B testing
2. Branch by Abstraction
For large changes, create an abstraction layer:
Step 1: Create abstraction
┌──────────────────────┐
│ Abstraction Layer │
├──────────────────────┤
│ Old Implementation │
└──────────────────────┘
Step 2: Build new behind abstraction
┌──────────────────────┐
│ Abstraction Layer │
├──────────────────────┤
│ Old │ New (disabled) │
└──────────────────────┘
Step 3: Switch to new
┌──────────────────────┐
│ Abstraction Layer │
├──────────────────────┤
│ New (active) │
└──────────────────────┘
Step 4: Remove old
┌──────────────────────┐
│ New Implementation │
└──────────────────────┘
3. Strong CI/CD
Every commit triggers:
- Automated tests
- Linting
- Build verification
- Security scans
- Deployment to staging
4. Code Review at Speed
- Small PRs = fast reviews
- Automated checks reduce manual work
- Pair programming can replace formal review
Trunk-Based vs Gitflow
| Trunk-Based | Gitflow |
|---|---|
| One main branch | Multiple long-lived branches |
| Short-lived branches | Long-lived feature branches |
| Continuous deployment | Scheduled releases |
| Feature flags | Feature branches |
| Simple | Complex |
| High discipline required | More structure provided |
Release Strategies
Continuous Deployment
Every green build goes to production:
commit → tests → staging → production
(automatic if green)
Release Branches (if needed)
For versioned releases, create branches from trunk:
main: ──●──●──●──●──●──●──●──
↓ ↓
release: 1.0 1.1
Release branches only receive fixes, no new features.
Scaling Trunk-Based Development
For Large Teams
- Strong CI is essential
- Use feature flags extensively
- Consider "scaled trunk" with release branches
- Automated testing at all levels
For Monorepos
# Only run affected tests
npm test --affected
# Only build changed packages
npm build --affected
Team Size Guidelines
| Team Size | Approach |
|---|---|
| 1-5 | Direct commits to trunk possible |
| 5-20 | Short-lived branches with PR |
| 20+ | Short branches + strong CI + feature flags |
Benefits
- Faster integration: No merge hell
- Continuous delivery: Always deployable
- Reduced complexity: Fewer branches to manage
- Team collaboration: Everyone sees all changes
- Quick feedback: Issues caught immediately
Challenges
Incomplete Features
Solution: Feature flags
// Hide incomplete feature
if (isFeatureEnabled('new-dashboard')) {
showNewDashboard();
}
Breaking Changes
Solution: Expand-Contract pattern
// Step 1: Expand (add new, keep old)
function processPayment(amount, currency = 'USD') { ... }
// Step 2: Migrate callers
// ... update all callers to use new signature ...
// Step 3: Contract (remove old)
function processPayment(amount, currency) { ... }
Code Review Speed
Solution: Small PRs + automation
- PRs should be < 200 lines
- Automated tests catch most issues
- Pair programming for complex changes
Making the Switch
From Feature Branches
- Shorten branch lifespans gradually
- Introduce feature flags
- Improve CI/CD pipeline
- Train team on practices
From Gitflow
- Stop creating release branches
- Merge develop into main
- Use only main + short branches
- Add feature flags for incomplete work
Summary
- Single main branch (trunk) is the source of truth
- Branches live hours to days, not weeks
- Feature flags enable incomplete feature merging
- Strong CI/CD is essential
- Small, frequent changes beat large, infrequent ones
- Works well for continuous deployment
- Requires team discipline and good practices
In the next lesson, we'll explore the Forking Workflow for open source contribution.

