What Is Trunk Based Development? A Solo Dev's Take
Summary
What is trunk based development? It is a branching model where everyone merges small changes into one shared branch, usually main, at least once a day. Branches live for hours, unfinished work hides behind feature flags, and CI keeps the trunk releasable. DORA research links the practice to faster, more stable delivery. For solo devs and small teams it means fewer merge conflicts, smaller reviews and deploys that feel boring.
What is trunk based development? It is a branching model where everyone merges small changes into one shared branch, usually called main or trunk, at least once a day. Branches, if you use them, live for hours, not weeks. Unfinished work ships hidden behind a flag so the trunk stays releasable at every commit. That is the whole idea, and it is less exotic than the name suggests.
Here is the scene that makes it concrete. You open a side project you left for three weeks. The feature branch is 41 commits behind main, two files have conflicts, and the thing you were building no longer matches the code around it. Trunk based development is the habit that stops that scene from happening.
What trunk based development actually means
The trunkbaseddevelopment.com reference site defines it as a source-control model where developers collaborate on one shared branch and avoid other long-lived development branches. Direct commits to trunk are fine for very small teams. Pull requests are fine too, as long as the feature branches stay short-lived and come from one workstation's effort.
Three rules carry most of the weight.
Merge to trunk at least once every 24 hours.
Keep the trunk green: a broken build on main is the top priority for everyone.
Hide incomplete work with feature flags instead of keeping it on a side branch.
Notice what is missing. There is no develop branch, no long release branch per feature, no integration phase at the end where everyone finds out their code does not fit together. Here is what bites in practice with the older models: the pain is saved up and paid all at once.

Why it beats long-lived branches for most small teams
Long-lived branches are a loan. Every day a branch lives, it drifts a little further from main, and the interest shows up as merge conflicts, stale assumptions and reviews nobody can finish because the diff touches 60 files.
DORA's capability page on trunk-based development ties three practices to better delivery speed, stability and availability, based on its State of DevOps research. Have three or fewer active branches in the repository. Merge to trunk at least once a day. Avoid code freezes and integration phases. Those are concrete, measurable targets, which is rare in this field.
For a solo dev or a team of three, the argument is even simpler. Small merges are easy to review, easy to revert and easy to understand six months later when you are reading git blame at 22h wondering what past you was thinking.
Three reasons to do it, one reason not to. The reasons: smaller diffs, faster feedback from CI, and a main branch you can deploy on a Friday without sweating. The reason not to: if your tests are thin, merging daily just spreads breakage faster. We get to that below.
Short-lived branches or committing straight to main?
Both count as trunk based development. The difference is how much safety you want before code lands.
Committing directly to main works when you are alone or in a pair, your local build runs in under a minute, and you trust your tests. It is the fastest loop there is. Most solo builders already do this without calling it anything.
Short-lived branches with a pull request make sense once a second or third person joins, or when you want CI to run on a clean checkout before merge. The discipline is in the word short. A branch that survives past the next day is already drifting toward the model you are trying to leave.
A practical routine that holds up:
Pull main, branch with a name that says what the change is.
Make the smallest change that moves things forward, and run the full local build.
Open the PR, let CI run, merge the same day.
Delete the branch. Do not let them pile up.
If a change cannot be done in a day, the answer is not a longer branch. The answer is to slice the change thinner.
How do you ship half-finished work without breaking main?
This is the question that stops most people. If you merge daily, you will merge code for features that do not exist yet. Two techniques handle it.
The first is the feature flag. The new code path is merged but switched off, so users never see it. A flag can be as dumb as a boolean in an environment variable:
const showNewCheckout = process.env.FEATURE_NEW_CHECKOUT === "true";
export function Checkout() {
return showNewCheckout ? <NewCheckout /> : <OldCheckout />;
}That is enough for a side project. When you need targeting, gradual rollouts or a kill switch without a redeploy, a managed service earns its place.
The second technique is branch by abstraction, for bigger changes like swapping a database client or a payment provider. You put an interface in front of the old implementation, build the new one behind the same interface, move callers over piece by piece, then delete the old one. Every step is a small merge to trunk and nothing ever sits on a long branch.

One honest caveat on flags: they are debt. A flag that stays in the code for a year is a branch in disguise. Give each flag an owner and a removal date, and delete it when the feature is fully rolled out.
What your CI needs before you try this
Trunk based development without a safety net is just fast breakage. You need three things in place before you commit to a daily merge habit.
A build that runs on every push and finishes in minutes, not half an hour.
Tests that fail when something real breaks. Coverage numbers matter less than whether a bad change gets caught.
A fast way to roll back: revert the commit or flip the flag off.
Static analysis is a cheap extra layer. It catches a class of problems, such as obvious bugs, security smells and duplicated code, before a human reads the diff.
If you are the only reviewer, tooling that points at risky hotspots helps even more, because nobody else will tell you that the file you keep touching is turning into a mess.
Skip the idea that you need a heavyweight pipeline on day one. A single workflow file that installs, lints, tests and deploys main is a perfectly good start. Tested, not optimal, and worth doing anyway: it is the first version that works, and you can tighten it later.
Release branches, hotfixes and the things that still need care
Trunk based development does not forbid release branches. Some teams cut a branch from trunk just before a release, harden it, ship it and delete it. Others release straight from trunk and fix forward when a bug shows up. For a web app deployed several times a week, fixing forward is almost always simpler.
Mobile apps and anything with a slow store review cycle are a different story. There you may keep a short-lived release branch per version so you can patch what is already in users' hands. Even then, the rule holds: fixes land on trunk first, then get cherry-picked, never the other way round.
Hotfixes follow the same logic. Fix on trunk, deploy, done. A separate hotfix branch that never gets merged back is how teams end up with two diverging histories.

A realistic first week
Day one, check how your repo branches today. List the open branches and note the age of each. Anything older than a few days is a candidate for merging or deleting. This alone often shows where the friction lives.
Day two, add the flag mechanism. Even an environment variable is fine. Pick one in-progress feature and put its entry point behind it, then merge what you have.
Day three to five, change the habit. Cut each task into pieces that can land in a day, and merge each piece when CI passes. Expect the first pieces to feel too small. They are not. A commit that adds a dormant database column or an unused function is a perfectly good unit of progress, because it is safe, reviewed and already integrated.
By the end of the week you will know two things: whether your tests are trustworthy enough, and which parts of your code resist small changes. Both are useful, and neither shows up while you work on long branches.
You do not need a dashboard to tell. Look at how long your branches live, how often main is red, and how long a change takes to get from first commit to production. If branch age is shrinking and deploys are getting boring, the habit is paying off.
If you want numbers on user-facing effects of what you ship behind flags, an experimentation tool can tie a rollout to real metrics instead of gut feeling.
For a team of one, a plain notebook works too. Write down merge-to-deploy time every week for a month. The trend tells you more than any single figure.
Should you switch, or wait?
Switch if you work alone, in a pair, or in a small team with tests you half trust and a CI you can improve. The cost of trying is a week of slightly uncomfortable small commits. The cost of staying on long branches is paid in conflicts and slow reviews, and it grows with every collaborator.
Wait if you have no automated tests at all and no way to roll back. Fix that first, because daily merges into an untested trunk only move the pain around.
It is not a perfect method. It is a workable one. Pick the next small change in your current project, merge it today, and see how it feels. What is the smallest slice of your current feature that you could ship before tonight?