# BranchPicker
URL: /docs/primitives/branch-picker

Navigate between message branches, which are alternative responses the user can flip through.

> For AI agents: a documentation index is available at [llms.txt](/llms.txt). Use `.md` for canonical markdown pages; `.mdx` is kept as a backwards-compatible alias on supported URL paths.

The BranchPicker primitive lets users navigate between message branches, which are alternative responses generated by editing a message or regenerating a reply. It's used alongside ActionBar inside message components.

Choose one:

**Preview**

\[interactive preview omitted]

**Code**

```
import {
  BranchPickerPrimitive,
  MessagePrimitive,
} from "@assistant-ui/react";
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";

function AssistantMessage() {
  return (
    <MessagePrimitive.Root className="flex flex-col items-start gap-1">
      <div className="rounded-2xl bg-muted px-4 py-2.5 text-sm">
        <MessagePrimitive.Parts />
      </div>
      <BranchPickerPrimitive.Root className="inline-flex items-center gap-0.5 text-xs">
        <BranchPickerPrimitive.Previous className="flex size-6 items-center justify-center rounded-md disabled:opacity-30">
          <ChevronLeftIcon className="size-3.5" />
        </BranchPickerPrimitive.Previous>
        <span>
          <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
        </span>
        <BranchPickerPrimitive.Next className="flex size-6 items-center justify-center rounded-md disabled:opacity-30">
          <ChevronRightIcon className="size-3.5" />
        </BranchPickerPrimitive.Next>
      </BranchPickerPrimitive.Root>
    </MessagePrimitive.Root>
  );
}
```

## Quick Start

Minimal example:

```
import { BranchPickerPrimitive } from "@assistant-ui/react";

<BranchPickerPrimitive.Root>
  <BranchPickerPrimitive.Previous>←</BranchPickerPrimitive.Previous>
  <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
  <BranchPickerPrimitive.Next>→</BranchPickerPrimitive.Next>
</BranchPickerPrimitive.Root>
```

`Root` renders a `<div>`, `Previous` and `Next` render `<button>` elements that auto-disable at boundaries. `Number` and `Count` render plain text (the current branch index and total count).

> [!info]
>
> BranchPicker must be placed inside a `MessagePrimitive.Root` because it reads branch state from the nearest message context.

> [!info]
>
> Runtime setup: primitives require runtime context. Wrap your UI in `AssistantRuntimeProvider` with a runtime (for example `useLocalRuntime(...)`). See [Pick a Runtime](/docs/runtimes/pick-a-runtime).

## Core Concepts

### Branch Navigation

`Previous` and `Next` buttons automatically disable at boundaries. `Previous` is disabled on the first branch, and `Next` is disabled on the last. Both also disable while the thread is running if the runtime doesn't support `switchBranchDuringRun`.

### Number & Count

`Number` and `Count` are text-only primitives that render raw numbers with no wrapping element. Use a `<span>` if you need to style them:

```
<span className="tabular-nums">
  <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
</span>
```

### hideWhenSingleBranch

The `hideWhenSingleBranch` prop on `Root` hides the entire picker when there's only one branch. This is a common production pattern to reduce visual clutter:

```
<BranchPickerPrimitive.Root hideWhenSingleBranch>
  <BranchPickerPrimitive.Previous>←</BranchPickerPrimitive.Previous>
  <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
  <BranchPickerPrimitive.Next>→</BranchPickerPrimitive.Next>
</BranchPickerPrimitive.Root>
```

### Context Requirement

BranchPicker reads branch state from the nearest message context. It must be placed inside a `MessagePrimitive.Root`, either directly or nested inside your message component.

## Parts

### Root

Container with optional `hideWhenSingleBranch`. Renders a `<div>` element unless `asChild` is set.

```
<BranchPickerPrimitive.Root hideWhenSingleBranch className="inline-flex items-center gap-1">
  <BranchPickerPrimitive.Previous>←</BranchPickerPrimitive.Previous>
  <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
  <BranchPickerPrimitive.Next>→</BranchPickerPrimitive.Next>
</BranchPickerPrimitive.Root>
```

- `render?`: `ReactElement<unknown, string | JSXElementConstructor<any>>`
- `hideWhenSingleBranch`: `boolean` (default `false`) — Whether to hide the branch picker when there's only one branch available. When true, the component will only render when multiple branches exist.

### Previous

Button that selects the previous branch. Renders a `<button>` element unless `asChild` is set.

```
<BranchPickerPrimitive.Previous>Previous</BranchPickerPrimitive.Previous>
```

### Next

Button that selects the next branch. Renders a `<button>` element unless `asChild` is set.

```
<BranchPickerPrimitive.Next>Next</BranchPickerPrimitive.Next>
```

### Number

Displays the current branch number.

```
<BranchPickerPrimitive.Number />
```

### Count

Displays the total number of branches for the current message.

```
<BranchPickerPrimitive.Count />
```

## Patterns

### Standard Picker with Icons

```
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";

<BranchPickerPrimitive.Root
  hideWhenSingleBranch
  className="inline-flex items-center gap-1 text-xs text-muted-foreground"
>
  <BranchPickerPrimitive.Previous className="size-6 rounded-md hover:bg-muted disabled:opacity-30">
    <ChevronLeftIcon className="size-3.5" />
  </BranchPickerPrimitive.Previous>
  <span className="tabular-nums">
    <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />
  </span>
  <BranchPickerPrimitive.Next className="size-6 rounded-md hover:bg-muted disabled:opacity-30">
    <ChevronRightIcon className="size-3.5" />
  </BranchPickerPrimitive.Next>
</BranchPickerPrimitive.Root>
```

### Custom Elements with asChild

```
<BranchPickerPrimitive.Previous asChild>
  <MyIconButton tooltip="Previous branch">
    <ChevronLeftIcon />
  </MyIconButton>
</BranchPickerPrimitive.Previous>
```

The primitive's disabled state and click handler merge onto your element.

### Inside a Message Footer

The most common pattern places the BranchPicker alongside an ActionBar in a message footer:

```
function AssistantMessage() {
  return (
    <MessagePrimitive.Root>
      <div className="rounded-xl bg-muted p-3">
        <MessagePrimitive.Parts />
      </div>
      <div className="flex items-center justify-between">
        <BranchPickerPrimitive.Root hideWhenSingleBranch>
          {/* prev / number / count / next */}
        </BranchPickerPrimitive.Root>
        <ActionBarPrimitive.Root>
          <ActionBarPrimitive.Copy>Copy</ActionBarPrimitive.Copy>
          <ActionBarPrimitive.Reload>Reload</ActionBarPrimitive.Reload>
        </ActionBarPrimitive.Root>
      </div>
    </MessagePrimitive.Root>
  );
}
```

## Relationship to Components

The shadcn [Thread](/docs/ui/thread) component includes a BranchPicker in both AssistantMessage and UserMessage footers, with `hideWhenSingleBranch` enabled. If the default layout works, use the component. Reach for `BranchPickerPrimitive` directly when you need a custom position, different styling, or a non-standard branch navigation experience.

## API Reference

For full prop details on every part, see the [BranchPickerPrimitive API Reference](/docs/api-reference/primitives/branch-picker).

Related:

- [ActionBarPrimitive API Reference](/docs/api-reference/primitives/action-bar)
- [MessagePrimitive API Reference](/docs/api-reference/primitives/message)