# Stacked Pull Requests on GitHub: A Practical Guide to the New Workflow

Pull requests are where code review happens, but they have a scaling problem. The bigger a feature gets, the bigger its pull request gets, until you end up with a single change that spans thousands of lines and dozens of files. Nobody can review that well, the author is blocked until it lands, and the branch drifts further from `main` with every passing day.

On July 30, 2026, GitHub shipped its answer to this in public preview: [stacked pull requests](https://github.blog/changelog/2026-07-30-stacked-pull-requests-are-now-in-public-preview/). The pattern has existed for years in third-party tools like Graphite and Sapling, and inside companies like Meta and Google, but **it is now native to GitHub itself** and wired into the CLI, github.com, the mobile app, and coding agents like GitHub Copilot.

This guide covers why large pull requests hurt, what stacking actually is, and how to build, review, and merge a stack using the `gh stack` CLI extension. Since the feature is in public preview, some details may change as it rolls out.

<iframe class="aspect-video h-auto" width="100%" height="315" src="https://www.youtube.com/embed/3Z1xcfF2xlY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## Why monolithic pull requests slow teams down

Before the stacked workflow makes sense, it helps to be precise about what goes wrong with one giant pull request. The friction shows up in two places: the review itself, and everything that happens while the review is pending.

### Review fatigue

Reviewing a large diff is like proofreading a 500-page manuscript in one sitting. You start sharp, but attention fades, and the subtle problems slip through. A wall of code produces predictable results.

Reviewers tend to skim. Faced with an overwhelming diff, it is easier to scan for obvious mistakes than to reason about architecture or trace a subtle bug, so the feedback gets shallower. Large pull requests also sit in the queue for days, because a proper review needs a large uninterrupted block of time that is hard to find. And when a reviewer does surface several issues, the conversation turns into a tangle of comments and replies that is difficult to track.

### Blocked work and rebase churn

The cost is not only in the review. The author is often stuck too, unable to start dependent work until the whole feature is approved.

Meanwhile `main` keeps moving. Other people merge their changes, and the large feature branch falls behind, so the author has to keep rebasing on top of the latest `main`. Each rebase risks conflicts, and those conflicts get harder to resolve as the change grows and more commits land in between. A single change request from a reviewer can trigger another round of rework and another painful rebase.

Stacking is designed to remove this entire category of pain by breaking one large change into small, ordered pieces that move independently.

## What stacked pull requests are

The idea is simple even if the mechanics take a little getting used to. In GitHub's framing, stacked pull requests let you break a large change into a chain of smaller, dependent pull requests that you can review and merge independently.

![A screenshot of the GitHub documentation highlighting the core definition of Stacked Pull Requests.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/fbaa679b-3798-4236-acc0-0c57bf2e7e00/lg2x =1280x720)

### A chain of dependent PRs

A stack is a series of pull requests in the same repository where each one targets the branch of the pull request below it, forming an ordered chain that lands on a single branch, usually `main`. The bottom pull request holds the most foundational change and targets `main` directly. Each pull request above it targets the branch of the one beneath it.


Say you are building a user profile feature. A stacked version might look like this:

1. `setup-database-schema` targets `main`. It adds only the migrations and models for the profile. Small, self-contained, quick to review.
2. `add-api-endpoints` targets `setup-database-schema`. It adds the routes that talk to the new schema, reviewable with the full context of the database change beneath it.
3. `build-frontend-profile-page` targets `add-api-endpoints`. It adds the UI that consumes those endpoints.

Each reviewer gets a focused diff for one layer, and foundational decisions get approved before anything depends on them.

### Git branches versus GitHub's tooling

It is worth being clear that stacking is a feature GitHub built on top of [Git](https://git-scm.com/), not a part of Git itself. You have always been able to branch off another branch. What was missing was tooling to manage the resulting chain of pull requests without a lot of manual bookkeeping.

That is what GitHub added. The platform now recognizes a chain of pull requests as one cohesive unit, gives it a dedicated interface for visualizing and navigating the layers, and ships a CLI extension that automates the creation and rebasing that used to be done by hand.

## Before you start: install the gh stack extension

The smoothest way to work with stacks is the [GitHub CLI](https://cli.github.com/) and its `gh stack` extension. Note that `gh stack` is a separate extension, not part of the core CLI, so you install it explicitly after installing `gh` itself. This is the step most people miss.

You will need GitHub CLI version 2.90.0 or later and Git 2.20 or later.

First install the CLI if you do not already have it:

```bash
# macOS
brew install gh

# Windows
winget install --id GitHub.cli

# Debian / Ubuntu
sudo mkdir -p -m 755 /etc/apt/keyrings && wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null
sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update
sudo apt install gh
```

Authenticate with your account:

```bash
gh auth login
```

Then install the stacking extension:

```bash
gh extension install github/gh-stack
```

If you want your coding agent to drive stacks for you, install the matching skill as well. This teaches agents like GitHub Copilot how to break a change into layers instead of dumping everything into one diff:

```bash
gh skill install github/gh-stack
```

With that in place, you are ready to build a stack.

## Building a stack with the GitHub CLI

The workflow below builds a three-layer feature: a database layer, an API layer, and a frontend layer. You commit to each branch as you normally would, and the extension handles the branch chaining and pull request wiring.

### Initialize the stack

From inside your repository, initialize a stack. This creates a tracking entry and your first branch, and prompts you to name it. By default the stack uses your repository's default branch, such as `main`, as the trunk, though it can target any branch.

```bash
gh stack init
```

Name the first branch `setup-database` when prompted. That branch is now the top of the stack.

![A view of the terminal in a text editor showing the `gh stack init setup-database` command being run.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/958e470d-04f5-43af-18ab-6db223441e00/md2x =1280x720)

### Commit your first layer

Work on `setup-database` exactly as you always do. To keep the example simple, edit `README.md` and commit. Each layer can hold as many commits as you need.

```bash
git add .
git commit -m "feat: implement initial database schema"
```

### Add the next layer

When the first layer is committed, add the next one. `gh stack add` creates a new branch from your current branch, not from `main`, and checks it out for you.

```bash
gh stack add setup-api
```

Now on `setup-api`, make and commit your changes. To show that a layer can hold multiple commits:

```bash
git add .
git commit -m "feat: add GET endpoint"

git add .
git commit -m "feat: add POST endpoint"
```

There is a handy shortcut worth knowing. `gh stack add -Am "MESSAGE"` stages everything, commits, and creates the next branch in one step. If the current branch has no commits yet, the commit lands there; if it already has commits, a new branch is created.

```bash
gh stack add -Am "API routes"
```

### Add a final layer

Repeat once more for the frontend layer.

```bash
gh stack add setup-frontend
git add .
git commit -m "test: add unit tests for API"
```

You now have a local stack of three chained branches, each with its own commits.

### Push and submit the stack

Push every branch to the remote:

```bash
gh stack push
```

Then create the pull requests and link them as a stack on GitHub:

```bash
gh stack submit
```

Each pull request is created with the correct base branch. Your first branch targets `main`, `setup-api` targets `setup-database`, and `setup-frontend` targets `setup-api`. Reviewers see only the diff for their layer, and the pull requests are linked together so anyone can see the order and jump between them.

![The interactive terminal UI provided by `gh stack submit`, showing the list of branches in the stack on the left and the title/description fields for the selected PR.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/07da1180-05dd-444c-3d76-653504e30800/md1x =1280x720)

At any point you can inspect the whole stack, including each branch, its linked pull request, its status, and its latest commit:

```bash
gh stack view
```

## Reviewing and merging stacks on GitHub

Once the stack is submitted, the workflow moves to github.com, where the interface is built around the chain rather than the individual pull request.

### The stack map and PR list

In the pull requests list, each pull request that belongs to a stack shows an indicator of its position, like `1/3`, `2/3`, and `3/3`, so you can tell at a glance that they are one ordered feature.

![The GitHub Pull Requests list page, with three PRs clearly marked with stack icons (1/3, 2/3, 3/3).](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/e4bb463c-770e-4bb4-d2dc-58a0d41ea000/lg2x =1280x720)

Open any pull request and you get a stack map at the top. It shows the full chain, highlights where the current layer sits, lists each pull request with its review status, and lets you move between layers in one click. Reviewers can each take a different layer in parallel without blocking the others.

### Merging from the bottom up

Stacks merge from the bottom up, and GitHub handles the rebasing that used to make this the worst part of the workflow. You can merge a single pull request, merge a contiguous group, or land an approved pull request along with every unmerged layer beneath it in one operation.

![The UI widget within a pull request showing the full stack and the prominent "Merge stack" button.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/ecaa2f85-51c0-49d8-e2a3-f60a54da5800/md1x =1280x720)

When you merge the pull request at the bottom of the stack, GitHub automatically rebases the remaining branches so the next one targets your default branch. You do not rebase by hand, and you do not walk through the old, error-prone sequence of merging one pull request, waiting for CI, rebasing the next, resolving conflicts, and repeating.

Your existing rules still apply. Required reviews and branch protections are enforced against the final target branch, and CI runs as if each pull request targets that branch directly. Merge queue support for stacks is rolling out progressively.

## What you gain from stacking

Breaking a feature into an ordered chain of small pull requests changes the shape of the work in a few concrete ways.

Reviews get faster and sharper, because a focused diff is easier to reason about than a giant one, so feedback is more thorough and approvals come quicker. Your own velocity goes up, since you can submit a foundational layer and start the next one instead of waiting for a massive review to clear. The stack itself tells a clear story of how the feature was built, layer by layer, which helps anyone reading the history later. And integration gets safer, because the automated bottom-up merge and rebase remove most of the manual conflict resolution that large branches invite.

This matters more now that AI coding tools generate large diffs quickly. Several early users, including TED, Vercel, and jQuery, adopted stacking specifically because faster code generation had turned review into the bottleneck, and smaller dependency-ordered pieces make review both quicker and more accurate.

## Final thoughts

Stacked pull requests take a pattern that skilled teams already used through external tooling and make it a first-class part of GitHub. By splitting a complex change into small, dependent layers with real support for reviewing and merging them, GitHub is targeting one of the most persistent sources of friction in day-to-day development.

A few things are worth keeping in mind before you roll this out widely. **The feature is in public preview and subject to change.** Every branch in a stack has to live in the same repository, since cross-fork stacks are not supported, and stacking is not available in GitHub Desktop. With those caveats noted, this is a strong addition to the workflow, and the `gh stack` extension is the fastest way to try it on your next large feature.