# How Ego‑Browser Handles Browser Navigation, Tab Management, and the openOrReuseTab Function

> Discover how Ego-Browser simplifies tab management and navigation using the openOrReuseTab function. Learn how CDP operations are abstracted for efficient browser control.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: how-to-guide
- Published: 2026-08-07

---

**Ego‑Browser abstracts Chrome DevTools Protocol (CDP) operations into high‑level JavaScript helpers, with all tab lifecycle logic centralized in [`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts) and exposed through the `browser` façade in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts).**

The **ego‑browser** navigation system provides deterministic tab handling for automation agents. Rather than managing raw CDP commands, developers interact with a unified API that handles listing, switching, creating, reusing, and closing tabs while abstracting low‑level protocol complexity.

## Core Navigation Architecture

The navigation subsystem lives in three primary locations:

- **[`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts)** — Core implementation of tab operations
- **[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)** — `browser` façade exposing helpers to agent scripts
- **[`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts)** — Method signatures and help text generation

According to the citrolabs/ego‑browser source code, the `browser` object is assembled around line 770 in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts):

```typescript
// src/helpers.ts (excerpt)
export const browser = {
  listTabs,
  currentTab,
  switchTab,
  newTab,
  openOrReuseTab,
  closeTab,
  // …
};

```

## Tab Listing and Selection

### listTabs

The `listTabs` function queries the Ego runtime for all browser tabs. In [`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts) (lines 112–130), it filters internal Chrome tabs unless `includeChrome: true` is passed.

Returns: `Array<{targetId, title, url, active, index}>`

### currentTab

Located at lines 135–146 in [`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts), `currentTab` retrieves the list from `listTabs()` and returns the active tab—or the first tab if none are explicitly active. Throws if no tabs exist.

## Tab Switching and Creation

### switchTab

The `switchTab` implementation (lines 151–161) validates the supplied **target ID**, activates it via CDP's `Target.activateTarget`, invalidates the session cache, and records the new preferred target.

### newTab

At lines 165–174, `newTab` calls `browserEgo().createTab(url)` with a default of `about:blank`, returning the freshly created `targetId`.

## The openOrReuseTab Helper: Deep Dive

The **`openOrReuseTab`** function (lines 176–200 in [`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts)) is the centerpiece of ego‑browser's **browser navigation** system. It implements intelligent tab reuse with configurable matching logic.

### Implementation Flow

1. **Fetch** current tab list via `listTabs()`
2. **Match** requested URL against existing tabs using the `match` option
3. **Reuse**: If matched, call `switchTab`, optionally wait for document load, apply settle delay
4. **Create**: If no match, invoke `newTab`
5. **Return**: Unified object `{targetId, url, title, active, reused}`

### Match Modes

| Mode | Description |
|------|-------------|
| `exact` | Full URL equality |
| `origin` | Same protocol + host |
| `origin+path` | Same origin including path |
| `includes` | URL contains the match string |

### Options Interface

```typescript
{
  match?: 'exact' | 'origin' | 'origin+path' | 'includes';
  wait?: boolean;           // wait for document load
  timeout?: number;         // load wait timeout (ms)
  settle?: number;          // extra pause after load (ms)
}

```

### Code Examples

**Reuse exact match with full load waiting:**

```javascript
await browser.openOrReuseTab('https://news.ycombinator.com', {
  match: 'exact',
  wait: true,
  timeout: 15000,
  settle: 500,
});

```

**Reuse any tab from same origin:**

```javascript
await browser.openOrReuseTab('https://example.com/page', {
  match: 'origin',
  wait: true,
});

```

**Force new tab behavior:**

```javascript
// Returns { reused: false } when new tab created
const result = await browser.openOrReuseTab('https://github.com', {
  match: 'none',  // or omit match entirely for guaranteed new tab
});

```

The public signature is documented in [`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts):

```typescript
// src/format.ts (excerpt)
"browser.openOrReuseTab": {
  signature: "browser.openOrReuseTab(url, options?) => Promise<object>",
  examples: [
    "await browser.openOrReuseTab('https://example.com', { wait: true, timeout: 20000 })",
  ],
},

```

## Closing Tabs

The **`closeTab`** function (lines 212–233 in [`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts)) handles tab cleanup:

- Defaults to active tab if no target specified
- Validates target via CDP
- Sends `Target.closeTarget`
- Clears preferred target if closed tab was recorded as preferred
- Waits for tab disappearance when multiple tabs remain

```javascript
// Close active tab
await browser.closeTab();

// Close specific tab
await browser.closeTab({ targetId: 'ABC123...' });

```

## Supporting Infrastructure

### Wait Utilities

The `waitForDocumentLoad` helper used by `openOrReuseTab` resides in **[`src/driver/waits.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/waits.ts)**, providing robust page load detection beyond basic CDP events.

## Summary

- **Centralized implementation**: All tab operations live in [`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts)
- **Façade pattern**: [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) exposes clean `browser.*` API
- **Smart reuse**: `openOrReuseTab` eliminates redundant tabs via configurable URL matching
- **CDP abstraction**: No direct protocol handling required for common workflows
- **Deterministic behavior**: Clear `reused` flag in return values enables conditional logic

## Frequently Asked Questions

### What is the default match behavior in openOrReuseTab?

When no `match` option is provided, `openOrReuseTab` creates a new tab unconditionally. To enable reuse, explicitly set `match` to one of the supported modes: `exact`, `origin`, `origin+path`, or `includes`.

### How does ego‑browser handle waiting for page loads?

When `wait: true` is passed to `openOrReuseTab`, the function invokes `waitForDocumentLoad` from [`src/driver/waits.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/waits.ts), which monitors CDP lifecycle events until the document reaches a stable state or the `timeout` expires.

### Can I switch to a tab without knowing its targetId?

Direct `switchTab` requires a `targetId`. However, you can use `openOrReuseTab` with `match: 'origin'` or `match: 'includes'` to find and activate a tab by URL pattern without manually iterating through `listTabs()` results.

### What happens when closeTab removes the last tab?

The `closeTab` implementation only waits for tab disappearance when more than one tab remains. Closing the final tab triggers normal browser behavior—typically creating a fresh blank tab or closing the window, depending on Chrome configuration.