Trunk-Based Development
30 comments
·February 10, 2025jdlshore
0xbadcafebee
Not that it makes a ton of difference, but technically trunk-based development refers more to the branching model, while continuous integration is a larger concept combining specific tooling, methods, branching, etc. You can do continuous integration with other branching models[1].
Unless a team tries hard to stick to strict CI, they usually end up with long-lived feature branches, long integration cycles, and clumsy, irregular deployments to irregular environments. So many teams still don't "get" CI, and end up wasting a shitload of time.
[1] https://www.martinfowler.com/articles/continuousIntegration....
jdlshore
The article you referenced specifically says that “trunk-based development” is a synonym for “continuous integration.” Please see the section titled “What is the difference between continuous integration and trunk-based development?”
kspacewalk2
That's a nice bit of history, but that is no longer common usage. Terminology has a life of its own, it isn't owned by those who first use it.
tharkun__
Never mind the content marketing of the "article". Use whatever tool you want to. If all you have is `if env==dev|staging`, that's enough, no need for "Bucket" or whatever. In general terms though:
If you build your feature without wiring it up to the UI it means that you never integrate until the last moment. That way, you can't actually test a user interaction in an actually integrated fashion.
This is really bad, because you will find all the integration problems at the very last moment. Basically when you're about to give it to your customers.
Feature flagging combats that. It allows you to test the entire solution from the point of an actual customer, without exposing it to an actual customer.
hatthew
I am strongly opposed to feature flags and conditionals in the code, unless absolutely necessary. If you don't remove deprecated features/branches, your code will end up unmaintainable. If you do remove them, the removal is (in my experience) worse than dealing with merge conflicts. Version control is designed for the exact problem of having multiple implementations exist and merging them as needed. Why roll your own obtuse version control by having all branches in the same file simultaneously when you can just use git to have them exist in parallel universes?
There's value in putting a newly completed feature behind a feature flag so you can turn it off instantly in prod. There is much less value in putting dozens of not-yet-functional features behind feature flags that shouldn't be turned on for the next several weeks/months (or maybe never).
liuliu
So, I am not doing big development with hundreds / thousands engineers for quite some time. So I started to have sympathy to the other side of the story. The problem with feature branches, especially for frontend development, is that it is never just a "feature" (otherwise, you can gate it compile-time by just compiling out that feature module completely, or in nodejs terminology, treeshaking?).
It is a combination of some new UIs, some updates to some interfaces, some new capabilities to a new middleware and some new APIs to call backend. And you don't want to gate these behind a feature flag. And merging these into main branch while make sure when multiple person working on a feature branch know what commits they did on feature branch is in main branch and why a merge from main branch would just absorb these commits are tiring.
In these cases, trunk based development is really working for cases that not every developer is a git guru and can just navigate the merge back forth from main branch to feature branch and back. Yes, for these, subversion / perforce makes more sense, but everyone who is not git guru is still on git.
That coupled with inefficiencies of your CI system only runs on main branch and needs manual adjustment to run on a feature branch every time, it is easier to do it on the trunk.
Every problem is a tools problem, and people picks least resistance to make tools do what they want. There is no right or wrong, pick your poison wisely.
sunshowers
> Version control is designed for the exact problem of having multiple implementations exist and merging them as needed.
This is a common misconception! The primary purpose of version control is to answer discovery requests when the lawyers come knocking. :)
(I'm only half joking here. I do think VCS merges are generally not a good idea, for technical reasons like criss-cross merges being an issue.)
vishnugupta
> Why roll your own obtuse version control
This is exactly it. Feature flags sounds really good until one realizes that they have all the requirements of a version control. So much that it was even a running joke at Uber that one starts building feature flag and ends up with a version control.
The cruft of feature flag also makes it really hard to understand while reading a code, there’s a combinatorial explosion.
js2
Everything old is new again:
> Flickr is somewhat unique in that it uses a code repository with no branches; everything is checked into head, and head is pushed to production several times a day. This works well for bug fixes that we want to go out immediately, but presents a problem when we’re working on a new feature that takes several months to complete. How do we solve that problem? With flags and flippers!
jtreminio
> On top of that, once you finally get a feature merged and deployed, it can often happen that there’s a bug causing users to have a poor experience. Since your new feature lives directly in the code, deactivating it requires rolling back the code you merged, building it, waiting for the tests to run, and redeploying the application
Why aren’t you using feature flags to gate new behavior/functionality?
ashenke
This is literally what the article advocates. It pushes things to the extreme where every code you write would be on the main branch and behind a feature flag
zeendo
Every time this comes up it feels like two groups of people meet where one group either thought the other didn't exist or was much smaller than it really is. It's bizarre.
furyofantares
> Trunk-based development is the seemingly radical idea of a team working together on the same code base at the same time.
Seemingly radical, hm. I've never worked any other way in 20+ years.
weakfish
I’m gonna be honest, this sounds horrible. If you do adopt this though, why even use Git? Why not use Perforce or something?
kevmo314
As someone who uses this model with git, the main reason is because git is ubiquitous but I cannot get used to git's incredibly user unfriendly API. I've tried the feature branch approach and it doesn't click for me. Merge conflicts, lost changes, and git reset everywhere.
So in other words, I'm using this model because if I could use perforce I probably would, but git is everywhere.
Also, every time I bring up git's user unfriendliness, I'm always told it's not that hard and I'm holding it wrong. I'm sure I am now too, I just don't care.
smithcoin
Here is an article of how my team had accomplished this with GitHub actions I posted earlier: https://blog.gregweber.info/blog/github-actions-trunk-based-...
twic
I'd be interested to hear from anyone with substantial experience of trunk-based development who prefers a merge workflow, and can articulate why. Comments on TBD posts are usually either TBD enthusiasts, or people who have never used TBD and think it sounds stupid.
tcoff91
I have worked with trunk based development aka everyone just pushing change lists to perforce. I much prefer people making pull requests because I can make sure people fix things in code review before it gets merged to master.
I do absolutely hate however when someone works for 3 months on a mega PR and drops a +8000 -5000 on my head.
Ultimately both systems can work and both can suck.
gregmac
I echo this. No pull requests is awful. The only time it's worked well for me is with 2 or 3 people sitting next to each other, with the same mindset and coding style.
Every other time I've seen or worked with teams doing it, their codrle is, well, bad. It "works" but it is full of stuff half-done, "we'll clean that up later" - except it's been there for 3 years. And I'm looking at it because I'vr narrowed down a production problem I was called in to debug, that turns out to be crappy error handling with terrible logging that mislead everyone on what was going on. A proper PR should have flagged that and asked for something slightly better than logging "something went wrong" in an try..catch statement that spans many hundreds of lines of code.
Small, focused PRs are good. Easy to review, code gets merged fast, conflicts are minimized. Massive PRs are bad, they are hard to review (problems get missed) and slow to get approved. If they get reverted because of a problem it's a mess to fix. PRs that do multiple separate things (fix two unrelated bugs, add a feature, and reformat spacing in 30 files) are impossible.
If PRs are small and focused, the duration of time the branch is open, number of commits and the actual branching model does not matter.
Long lived branches are a pain to the author (they're who has to merge Main and resolve conflicts), but that's their choice.
inetknght
> I do absolutely hate however when someone works for 3 months on a mega PR and drops a +8000 -5000 on my head.
Trunk based workflow doesn't prevent that.
Moreover, heavy refactoring of code often ends up doing the same thing but much quicker.
JTyQZSnP3cQGa8B
TBD has merge requests. It lacks all the weird branches like hotfixes and goes back to a simpler set of branches. But MRs are still there. The author of the post is confused or is trolling on purpose of selling his tool. That is very dishonest.
stevage
I wonder how you code review a half implement feature.
nativeit
It's things like this that make me fear we may have reached peak dev.
darthrupert
How do you do code reviews with this model?
This is content marketing for a feature flagging tool called “Bucket.” I’m a big fan of trunk-based development, although I prefer its original name: continuous integration. (Sadly, that name has been coopted by tool vendors.)
A better alternative to feature flags is keystone interfaces. It’s very simple: build your new feature without wiring it up to the UI (or API). Test it using automated tests that bypass the UI. When it’s ready, wire it up, manually confirm that the automated tests didn’t miss anything, and release.