A Different Workflow#
During backend development, my Git habits were reasonable. Features were scoped, commits were deliberate, and branch names matched their contents at merge time. Moving to the frontend, that discipline quietly fell apart — and it took a while to notice.
The most honest explanation I have is that the feedback loop changed entirely. On the backend, the only way to verify that something worked was to run tests or fire requests at the API. That enforced a kind of rhythm: write, verify, commit, move on. The frontend is always running. Every change is visible immediately, and the temptation to keep going is constant.
The Product as Source of Truth#
At some point during frontend development, the running application became my source of truth instead of the code. Rather than asking “is this feature complete and coherent enough to commit?”, I was asking “does this look right?” — and if it did, I kept building on top of it.
The result was feature branches that drifted far beyond their original scope. A branch named feature/protected-route would quietly absorb three other concerns before it was merged, because those concerns were visible on screen and felt like part of the same flow. The branch name stopped reflecting the contents, and the commit history became harder to read as a result.
Why Scoping Is Harder With New Technology#
Part of the problem was practical. When working with familiar technology, it is possible to break a feature into small, ordered pieces before writing a single line — foundations first, then the components that build on them. With unfamiliar technology, that kind of upfront scoping is much harder. I often did not know what a feature actually required until I was halfway through it.
That uncertainty made it easy to justify larger branches. If I could not clearly define where one concern ended and another began, drawing a boundary felt arbitrary. So I did not draw one, and the branch kept growing.
In hindsight, the right response to that uncertainty was smaller commits within the branch rather than fewer, larger ones — capturing each stable state as I discovered it, rather than waiting until the feature looked finished on screen.
What the Backend Got Right#
The backend workflow forced patience. There was no visual output to chase, no immediate feedback beyond a passing test or a correct response. That slower loop naturally encouraged committing in slices, because each slice had a clear, verifiable outcome.
The frontend removed that constraint, and without it I defaulted to chasing the product. The habit I want to build is treating a coherent, working state in the code as the trigger for a commit — not a visual milestone in the browser.
Reflections#
This is not a problem unique to frontend development, and I do not think the tooling is to blame. The running application is useful — it is one of the things that makes frontend work satisfying. The discipline is in not letting it become the only measure of progress.
For the next project, I want to define commit boundaries before opening the browser, and treat drift as a signal to stop and reorient rather than a reason to keep going.
