Trunk-Based Development: A Guide for Beginners
Understanding trunk-based development: core concepts, best practices, and examples.

Prerequisites #
Before diving into trunk-based development, you should be familiar with:
• Basic Git commands (commit, push, pull, merge)
• Your team's primary programming language
• Basic concept of branches in version control
• What a pull request/merge request is
Key Terms to Know First BranchA separate line of development in your codebase. Think of it like creating a copy of your project where you can make changes without affecting the original version. Branches allow multiple developers to work on different features simultaneously without interfering with each other's work. When you're satisfied with your changes, you can merge your branch back into the main codebase.
Trunk/Main BranchThe primary branch (usually called 'main' or 'master') where all code eventually merges. This branch represents the single source of truth for your project and should always contain working, deployable code. In trunk-based development, this is where all feature branches merge into frequently, often multiple times per day. Think of it as the backbone of your project where all completed work comes together.
CI/CDContinuous Integration/Continuous Deployment - automated processes for integrating and deploying code. CI ensures that whenever code is pushed, it's automatically built and tested to catch problems early. CD takes this a step further by automatically deploying verified code to production environments. Together, they form a pipeline that helps teams deliver code changes more frequently and reliably.
Feature ToggleA switch in your code that turns features on/off without deploying new code. Feature toggles allow you to deploy incomplete features to production while keeping them hidden from users. They're like light switches in your code - you can turn features on for testing, specific users, or gradually roll them out to more people. This is especially useful in trunk-based development where code is merged frequently but might not be ready for all users.
Pull Request (PR)A request to merge your code changes into another branch. Pull requests are like asking for a code review - they show others what changes you've made and allow team members to comment, suggest improvements, or approve the changes. They serve as a checkpoint where code quality can be verified before it gets merged into the main branch. Think of it as asking for permission to add your changes to the shared codebase.
Merge ConflictWhen Git can't automatically combine changes from different branches. This happens when two developers modify the same lines of code in different ways. Git doesn't know which changes to keep, so it needs human intervention to resolve the conflict. It's like two people editing the same sentence in a document differently - someone needs to decide which version (or combination of versions) to keep.
What is Trunk-Based Development?Think of trunk-based development like working on a shared document with your team. Instead of everyone having their own copy (branch) for days or weeks, you:
- Make small changes frequently
- Update the main document (trunk) at least once a day
- Keep your personal copy (feature branch) for no more than 1-2 days
- Repository Structure
- Development Patterns
- Morning:
- Continuous Delivery Requirements
- Team Characteristics
- Project Types
- Team Scenarios
- Project Types
- Code Integration
- Team Practices
- Technical Requirements
- Deployment Strategy
- Development Metrics
- Team Metrics
Traditional Branching: main ----o--------o--------o-------- (rare merges) feature1 \----------------/ feature2 \------------------/ feature3 \---------------/ Trunk-Based Development: main ----o--o--o--o--o--o--o------ (frequent merges) feature1 \-/ feature2 \-/
feature3 \-/
In trunk-based development:
• All developers work on a single main branch (the "trunk")
• Changes are integrated frequently (ideally daily, but the exact frequency depends on team practices)
• Feature branches, when used, are short-lived (typically 1-2 days maximum)
• The trunk should always be in a releasable state
• Feature toggles are used to manage incomplete features in production
How to Recognize Trunk-Based DevelopmentA project using trunk-based development typically shows these characteristics:
• Single main branch with high commit frequency
• Few, short-lived feature branches
• No long-running release branches
• Automated CI/CD pipeline with frequent deployments
• Multiple commits to main branch daily
• Feature toggles in the codebase
• Comprehensive automated testing
• Emphasis on small, incremental changes
Common Pitfalls for Beginners 1. Making Too Big Changes❌ Wrong:
Working on a huge feature for days without merging
✅ Right:
Break down features into small, mergeable chunks
2. Not Testing Enough❌ Wrong:
Pushing directly to trunk without running tests
✅ Right:
Always run local tests before pushing
3. Poor Communication❌ Wrong:
Not telling team members about your changes
✅ Right:
Regularly update team on what you're working on
4. Fear of Merging Often❌ Wrong:
Holding onto your branch because you're nervous about merging
✅ Right:
Merge small changes frequently, use feature toggles for incomplete work
Your First Day with Trunk-Based DevelopmentNote: These commands are basic examples. Always follow your team's specific Git workflow and branch naming conventions. Some teams might use additional steps or different commands based on their setup.
Here's what a typical day looks like:
git checkout main git pull # Get latest changes
git checkout -b my-feature # Create new branch
2. <strong>During the day</strong>:
bash
git add .
git commit -m "Add login form validation"
git pull origin main # Stay up to date
3. <strong>End of day</strong>:
git push
# Create Pull Request
# Get review
# Merge to main
When to Use Trunk-Based Development
Ideal Scenarios
• Need for frequent releases
• Emphasis on fast feedback cycles
• Focus on continuous integration
• Strong automated testing practices
• Good code review culture
• Experienced in feature toggles
• Strong communication channels
• Web applications with frequent updates
• Services requiring rapid iteration
• Products with continuous delivery needs
When to Consider Alternatives
• Large teams without proper CI/CD infrastructure
• Teams new to automated testing
• Projects requiring extensive code review processes
• Systems requiring formal release processes
• Highly regulated environments
• Projects with long validation cycles
Implementation in React Applications
#
Note: The following examples demonstrate one way to implement trunk-based development in a React project. Keep in mind that different teams and organizations might have their own preferred approaches, tools, and patterns. The key is to understand the core principles and adapt them to your team's specific needs and requirements.
Let's start with a simple example that juniors can easily follow:
1. Basic Feature Toggle
Important: This is a simplified example for learning purposes. For production use, consider using established feature flag services or libraries that handle persistence, user targeting, and analytics.
// A simple feature toggle without complexity
const FEATURES = {
newHeader: false,
betaFeatures: false
};
function MyComponent() {
if (FEATURES.newHeader) {
return <NewHeader />;
}
return <OldHeader />;
}
2. Feature Implementation
// src/components/NewFeature.tsx import { useFeature } from '../features/FeatureManager'; export const EnhancedUserProfile: React.FC = () => { const isEnabled = useFeature('enhanced-profile'); if (!isEnabled) { return <UserProfile />; } return ( <div> <UserProfile /> <AdvancedSettings /> <ActivityFeed /> </div> );
};
• Small, frequent commits
• Clear team communication
• Well-defined component boundaries
• Automated conflict detection
2. Incomplete Features Challenge: Managing partially completed features in production code. Solution: Implement robust feature management:
// src/config/features.ts interface FeatureConfig { name: string; rolloutPercentage: number; enabledEnvironments: string[]; dependencies: string[]; } const featureConfigs: FeatureConfig[] = [ { name: 'enhanced-profile', rolloutPercentage: 20, enabledEnvironments: ['staging', 'production'], dependencies: ['user-settings', 'activity-feed'], }, ]; export const getEnabledFeatures = (environment: string): string[] => { return featureConfigs .filter(f => f.enabledEnvironments.includes(environment)) .map(f => f.name);
};
// src/components/UserDashboard.test.tsx import { render, screen, waitFor } from '@testing-library/react'; import { UserDashboard } from './UserDashboard'; describe('UserDashboard', () => { it('loads with feature flags', async () => { render( <FeatureProvider features={{ 'enhanced-profile': true }}> <UserDashboard /> </FeatureProvider> ); await waitFor(() => { expect(screen.getByTestId('enhanced-profile')).toBeInTheDocument(); }); }); it('handles disabled features gracefully', async () => { render( <FeatureProvider features={{ 'enhanced-profile': false }}> <UserDashboard /> </FeatureProvider> ); expect(screen.queryByTestId('enhanced-profile')).not.toBeInTheDocument(); });
});
Best Practices for Success #
• Merge to trunk at least once per day
• Keep feature branches short (1-2 days maximum)
• Use feature toggles for incomplete work
• Implement comprehensive automated testing
• Regular communication about feature development
• Quick code review turnaround
• Pair programming for complex features
• Clear documentation of feature toggles
• Automated CI/CD pipeline
• Comprehensive test coverage
• Feature toggle management system
• Monitoring and observability tools
• Automated deployment pipeline
• Rollback capabilities
• Feature toggle controls
• Gradual rollout mechanisms
Measuring SuccessKey metrics to track:
• Deployment frequency
• Lead time for changes
• Change failure rate
• Mean time to recovery
• Code review turnaround time
• Number of active branches
• Feature toggle usage
• Test coverage trends
Conclusion #
Trunk-based development is a powerful approach that can significantly improve development efficiency and software delivery when implemented correctly. However, it requires the right team culture, technical practices, and tooling to be successful. Consider your team's experience, project requirements, and existing infrastructure when deciding if trunk-based development is the right choice for your organization.
Further Reading• Atlassian's Guide to Trunk-Based Development
• Feature Toggles Best Practices
Troubleshooting Guide #
Common issues you might face and how to solve them:
1. Merge Conflicts
# If you get a merge conflict: git status # See which files are conflicted git pull origin main # Get latest changes # Fix conflicts in your editor git add .
git commit -m "Resolve conflicts"
// Always provide a fallback function MyFeature() { if (!isFeatureEnabled('newFeature')) { return <OldFeature />; // Fallback } return <NewFeature />;
}