# Fork vs Navigate_Tree Branching in Pi-Web: What's the Difference?

> Understand the core differences between fork and navigate_tree branching in pi-web. Fork creates new session files while navigate_tree uses existing ones to streamline your workflow.

- Repository: [Alex Yang/pi-web](https://github.com/agegr/pi-web)
- Tags: deep-dive
- Published: 2026-08-17

---

**Fork creates a new independent `.jsonl` session file with a unique ID, while navigate_tree switches the logical pointer within the existing conversation file without duplicating data.**

Pi-Web, the conversational agent interface from the `agegr/pi-web` repository, supports two distinct branching strategies that allow users to explore alternative conversation paths. Understanding the difference between fork and navigate_tree branching is essential for managing conversation history and storage efficiently. Both mechanisms are implemented in the core RPC manager but serve fundamentally different architectural purposes.

## Core Differences Between Fork and Navigate_Tree Branching

### What Fork Branching Does

When you initiate a **fork** operation—triggered by the Fork button on a user message—Pi-Web generates a completely new `.jsonl` session file that branches from a specific point in the current conversation. According to the source code in [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts) (lines 48-82), the `"fork"` command copies the conversation history up to the selected entry point and writes it to a new file with a freshly generated session ID. This new session maintains a link to its origin through the `parentSession` header field, allowing the sidebar to display it as a child entry while keeping the files physically separate.

### What Navigate_Tree Branching Does

In contrast, **navigate_tree** branching—triggered by the Continue button or BranchNavigator component—does not create new files. Instead, it moves the logical pointer (`leafId`) to a different entry within the same `.jsonl` file. The implementation in [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts) (lines 85-90) handles this via the `"navigate_tree"` command, which calls `inner.navigateTree()` to update the current leaf position. All branches share identical `parentId` values, and the UI switches the displayed context using `/api/sessions/[id]/context?leafId=` endpoints.

## Implementation Details in the Pi-Web Source Code

The central command dispatcher in [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts) differentiates these operations through distinct RPC commands. When the system receives a `"fork"` request, it creates a new session file and caches the `newSessionId`. For `"navigate_tree"` requests, it preserves the existing session ID and merely updates the internal navigation state.

```typescript
// Fork operation: Creates a new independent session file
await fetch(`/api/agent/${sessionId}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ type: 'fork', entryId: messageEntryId })
});
// Response contains newSessionId for the forked branch

```

```typescript
// Navigate_tree operation: Switches leaf within current session
await fetch(`/api/agent/${sessionId}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ type: 'navigate_tree', targetId: leafEntryId })
});
// SessionId remains unchanged; only the displayed leaf updates

```

## Storage Architecture and Session Identity

**Fork branching** results in multiple physical files on disk, each representing an independent conversation timeline. The original and forked sessions can diverge permanently without affecting each other, making this approach suitable for exploring radically different solutions that need separate persistence.

**Navigate_tree branching** maintains a single `.jsonl` file containing the entire conversation tree. The [`lib/session-reader.ts`](https://github.com/agegr/pi-web/blob/main/lib/session-reader.ts) module handles both forked and in-session branches during file reading operations, but navigate_tree scenarios rely on the `leafId` parameter to determine which branch is currently active. This approach minimizes storage overhead when exploring variations within the same conversational context.

## When to Use Each Branching Method

Use **fork branching** when you need to:

- Create a permanent divergence from the current conversation path
- Maintain separate, persistent histories that won't interfere with each other
- Explore alternative solutions that require independent session management

Use **navigate_tree branching** when you need to:

- Switch between existing branches within the same conversation history
- Minimize storage usage while exploring different lines of thought
- Quickly jump between previously generated responses without creating new files

## Summary

- **Fork** generates a new `.jsonl` file with a unique session ID via the `"fork"` command in [`rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/rpc-manager.ts), creating physically separate conversation histories linked by `parentSession` metadata.
- **Navigate_tree** updates the `leafId` pointer within the existing session file using the `"navigate_tree"` command, keeping the same session ID while changing the displayed conversation branch.
- Fork operations are ideal for permanent divergence, while navigate_tree is optimized for lightweight navigation between existing branches.
- Both operations are handled by the central RPC manager in [`lib/rpc-manager.ts`](https://github.com/agegr/pi-web/blob/main/lib/rpc-manager.ts), but they differ fundamentally in storage strategy and session identity management.

## Frequently Asked Questions

### Does forking a conversation affect the original session file?

No, forking creates a completely new `.jsonl` file while leaving the original session intact. The forked session references the original through the `parentSession` header field, but modifications to either file remain independent and stored separately on disk.

### Can I switch back to a previous branch after using navigate_tree?

Yes, because navigate_tree only changes the logical `leafId` pointer within the same file. You can use the BranchNavigator component or API calls to move between any existing branches in the conversation tree without losing data or creating additional files.

### Which branching method consumes more storage space?

Fork branching consumes significantly more storage because it duplicates conversation history into new `.jsonl` files. Navigate_tree branching adds no storage overhead since it operates within the existing file structure by updating pointer references.

### How does the UI distinguish between forked and navigated branches?

The sidebar displays forked sessions as child entries under their parent session, utilizing the `parentSession` linkage established during the fork operation. Navigate_tree branches appear within the same session entry, with the UI fetching different contexts via the `leafId` query parameter to `/api/sessions/[id]/context`.