Most software developers these days are familiar with the "GitHub Flow" way of building their applications. With this workflow, team members create a separate branch from their codebase and work on their task separately from the primary branch that has the latest up-to-date code. When their new changes are ready for review, they open a pull request (sometimes called "merge requests" on other platforms like GitLab) to have others review the changes, ask questions, and offer suggestions and improvements before merging the new updates to the codebase.
The intent behind this workflow is to give visibility into what others on the team are working on and to allow everyone an opportunity to chip in and provide their experience to ensure the codebase remains in a healthy and performant state throughout its lifetime.
Potential Problems With GitHub Flow
GitHub Flow works well for most teams, which is why it's become somewhat of a standard for developing software. However, it can also create some bottlenecks that slow down the entire team. The usual culprits of an inefficient GitHub Flow are:
- Team members submitting humongous pull requests that have dozens or even hundreds of commits, making it almost impossible to review unless someone has hours to spend on it.
- Pull requests that lack enough details to indicate the work done by the developer, leaving it up to the reviewers to figure out the changes made in the codebase on their own.
- A complete lack of context as to why the work done in the pull request is necessary for the project, beyond the scope of the changes.
These issues and others can significantly slow down project development due to the constant back-and-forth discussions that typically occur when clarifying the work done and the pull request's purpose. Beyond the added time commitments required to untangle these kinds of pull requests, a hidden and even worse problem is that it significantly affects the quality of the codebase because team members won't give these reviews the time needed to ensure things are okay. You've probably seen larger pull requests get approved and merged within minutes, where it's clear that the reviewer didn't review anything. Letting these slide often leads to an erosion of quality and trust across the board.
A New Approach: Writing Your Pull Request Description First
Throughout my career, I've experimented with different ways to try to improve the way I work and how I collaborate with others. After seeing the same issues with the GitHub Flow happen over and over across various teams, I began to think about how to improve upon this way of working. I've been adopting this new technique lately, and it's something that I haven't seen used in many places, but it's worked well for me. I'm calling it the Pull Request-Driven Development workflow.
This new tactic is simple: flip the GitHub Flow process on its head and write the pull request's description before committing to the work. The practice is simple:
- Step away from the code editor—don't even think about writing a single line of code yet.
- Before writing any code, open a draft pull request (or create a document that mimics one).
- Write the description as if you've already completed the work.
- Include what changes you'll make, why they're necessary, and any potential impacts that might affect the project.
- Review what you've written to identify gaps or potential obstacles that may come down the road.
- When you're satisfied with your pull request description, you can begin writing code, using the description as your guide.
The Benefits I've Experienced
This process sounds unintuitive at first. Why would someone spend time writing a pull request description when they probably don't know what to do or how to do it? I'd argue that's exactly why you should imagine you're creating a new pull request before jumping into the code, because it helps get your brain thinking about what's ahead instead of doing it as you go, which often doesn't produce the best work.
Here are a few of the benefits I've seen from my own experience since I began doing this practice.
It slows you down and helps detect blind spots
Probably the main reason why I have come to love this pull request-driven development workflow is that it has been very effective in helping me spot gaps in the work before I dive into the code. One of my favorite techniques as a developer is rubber duck debugging, made popular in the book The Pragmatic Programmer. The concept of rubber duck debugging is that when we take the time to explain our work to others, it can guide us to a solution like magic. Pull request-driven development is similar—instead of talking to an inanimate object, you're thinking through the problem by writing down how you believe the end result will be.
This thought process before the work is amazing at surfacing things you likely ignored earlier. A recent project I had was to help a startup build a reporting section on their app. As part of our initial conversation, I made sure to ask the relevant questions for a task like this: what data I needed to gather, where I could find the data, when the reports needed to go out, how to format each report, and so on. As I began the pull request-driven development workflow after our meeting, a few glaring omissions came to the surface. Would they need real-time reporting? How about security, and who would access the reports? I uncovered these issues in just a few minutes, rather than waiting days for them to happen when I'm neck-deep in code.
As a developer, there's nothing I love doing more than having a problem to solve in front of me and building its solution. But working this way often leads me down roads where I have to backtrack, refactor, modify, and even scrap days of work because I missed some crucial details. In the past, I would have immediately begun work on the reporting project as soon as the first meeting wrapped up. At best, I would have spotted these issues midway through and created some delays in delivering my work. At worst, I wouldn't have noticed the client needed something until much later, which risks having an unhappy client and one less project to work on.
It helps me explain myself better to others
We rarely work in a vacuum by ourselves, and that means we need to communicate and interact with others daily. The best developers and testers I know are the ones who can communicate the most effectively, whether it's with their technical teammates or non-technical stakeholders. Clarity is key when providing the information from your work because it eliminates confusion, doubts, and the complete waste of time that happens when we're not expressing ourselves appropriately.
Nowadays, many teams work either fully or partially in separate physical locations, making clear communication a more essential part of our work. Discussing work through tools like project trackers and chat rooms isn't the same as having everyone in the same place and on the same page, and this is where many problems begin to crop up. When the 2020 pandemic led companies to suddenly move to remote-only, the organizations that weren't prepared for this shift in communication were among the ones that struggled the most and sent out return-to-office mandates as soon as they possibly could.
The pull request-driven development methodology helps us slow down and be mindful about how we're communicating with the rest of the team relating to our work. It's especially true when working on distributed teams that are in different locations around the globe. I live in Japan, and work almost exclusively with teams who are on the other side of the world in wildly different time zones. The majority of my interactions with others are asynchronous, and I need to be extra sure that I'm giving all the information they need from me whenever I communicate with them. Taking the time to think and write down my thoughts avoids having to wait for days for a response or deal with misunderstandings.
It helps me question why I'm doing the work
In my opinion, good software development isn't only about implementing something well. It's also about figuring out if what we're doing is the best thing to do for ourselves, the company, and the benefit of others who will eventually use what we create. Just because we can create something doesn't mean that we should. The real skill isn't writing code, especially nowadays when you can ask ChatGPT or Claude and get something working in minutes. The true sign of expertise is recognizing when to use code as the solution to a problem.
Far too often, development teams spend lots of time hyping themselves up over implementing new functionality for their applications and end up wasting time building complex solutions from scratch (or getting an LLM to make it for them). Even worse, these solutions often end up completely unused. For instance, most startups I've worked with have spent considerable time building admin paneavails_server/pull/407ls for their applications, yet almost no one uses them. One company I worked with had an admin panel that was completely broken for over a year, and no one noticed it.
It happens to all of us. I'm embarrassed to count the number of times I've gotten excited by a new idea or project, and I instantly begin coding something up, only to realize that it's not a good use of time. The dozens of half-baked project folders on my hard drive are a testament to that. The pull request-driven development concept has helped me question the things that I'm doing and prevented me from investing time in work that won't yield the benefits that I expected in my initial excitement or the benefits I thought others would find valuable.
Why These Things Matter Beyond Just Code
The GitHub Flow process technically begins when a developer creates a new branch in the codebase. However, the key part happens after they spend hours or days working on their task, which is why the workflow has its problems, like bloated branches and unclear reasons for the work's existence. It's not uncommon for a developer to get into the flow of hacking away on their code, only to realize that they made a lot of widespread changes that cover a lot of ground. Some people also want to move on to the next thing as quickly as possible, so they open a new pull request with the barest of details and leave the reviewer to fend for themselves.
I've fallen into these traps many times, especially when I was less experienced. Over time, I've tried to correct this behavior by keeping my code changes small and providing as much detail as I can about what I did and why I did it. My recent pull requests show how much time I tend to put into making sure reviewers have all they need, with most of the content written before I did the work (admittedly, some might say this is too much for a one-commit branch, but I say the more, the better):

Although these shifts in the way I open pull requests helped others with their reviews, I still feel like opening a pull request after spending so much time deep in the work isn't the optimal way of handling these changes. Often, while opening a pull request and writing the details of the work, I realized that something was missing, or that I was finding it difficult to explain the changes I made because they crossed over into other domains that I shouldn't have done as part of my updates. With the pull request-driven development workflow, it's become a non-issue because I fully understand what I need to do before I do it.
The idea of writing a description of your work before doing it isn't original to me. The inspiration behind this workflow came from Amazon's "Working Backwards" methodology. When a team at Amazon plans to develop a new product, one of the first things they do is to come up with a mock press release geared toward their intended market that talks about the product's release. This press release contains all the details you'd expect from a real one, like the problems the product solves, the customer benefits, FAQs, and even quotes from team members talking about the product.
The teams at Amazon write up these faux press releases for potential new products before the real work begins. Its purpose is to determine whether their concepts are worth pursuing and to build something that people want (and, of course, for them to make boatloads of money). It's not a fool-proof method—remember how the Fire Phone release went? Still, it's a good way to put an end to new work when it's evident that something won't turn out well for them, saving them millions of dollars and their reputation in the process. This idea of vetting the work before it's done is the reason why I now write my pull request descriptions before going deep into the code.
Wrap Up
If you work in software, there's a good chance you've heard of countless development methodologies to help us write code more efficiently: test-driven development (TDD), behavior-driven development (BDD), story-driven development (SDD), and others. You may have worked on a team that follows one of these methodologies, either loosely or strictly. While I agree with the concept of most of these development techniques, none have stuck with me for too long. It's also a challenge to implement these behaviors on a team with varying skill levels and work preferences. One team I worked with attempted to go all in with story-driven development, and it was almost a disaster—I'll save that story (pun intended) for another day.
I've come to believe that the most effective techniques are the simpler ones that are flexible rather than strictly rigid frameworks imposed by a team. The pull request-driven development methodology I've described in this article isn't something that I learned from a YouTube video or conference. Instead, it naturally emerged from my desire to put more thought into the projects in front of me.
This workflow has served me well, especially as a mostly-solo developer working with others asynchronously, since it provides clarity for myself and those who will inevitably interact with what I produce. I don't use it for every little task that I have, but for larger chunks of work, taking a brief moment to become more deliberate with what I'll do instead of jumping straight into the code is a shift that gives me more peace of mind and the confidence that I'm doing the right thing. I encourage anyone working with software to experiment with this pull request-driven workflow and see how it can improve your work and make it easier to communicate with others.