# How ego-browser Manages Tabs with openOrReuseTab and ensureRealTab

> Discover how ego-browser uses openOrReuseTab and ensureRealTab to intelligently manage Chrome tabs, simplifying CDP interactions for a reliable agent API.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: internals
- Published: 2026-08-15

---

**The `ego-browser` module uses two core helper functions—`openOrReuseTab` for intelligent tab reuse and `ensureRealTab` for guaranteed access to non-internal pages—to abstract Chrome DevTools Protocol (CDP) complexity into a reliable agent-facing API.**

The `ego-browser` package in the citrolabs/ego-lite repository provides browser automation primitives that shield agent scripts from raw CDP mechanics. Its tab management system centers on **[`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts)**, which implements matching, creation, and validation logic, while **[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)** exposes these capabilities through a clean façade.

## How openOrReuseTab Opens or Reuses Tabs Intelligently

The `openOrReuseTab(url, options)` function eliminates duplicate windows by matching against existing tabs before creating new ones. This reduces resource overhead and maintains session continuity during multi-step automation workflows.

### Step 1: Scan for Matching Tabs

The function first retrieves filtered tab state via `listTabs({ includeChrome: false })`. This helper calls `browserEgo().listTabs()` and strips internal pages:

```typescript
const result = assertNoEgoError(await browserEgo().listTabs(), "listTabs");
// ...
.filter(tab => includeChrome || !INTERNAL_URL_PREFIXES.some(prefix => (tab.url || "").startsWith(prefix)))

```

The `INTERNAL_URL_PREFIXES` array screens out `chrome://`, `devtools://`, and similar browser-internal schemes that agents cannot interact with meaningfully.

### Step 2: Apply URL Matching Strategy

The `tabMatchesUrl` utility compares the requested URL against candidate tabs using four strategies (in order of strictness):

- **exact** – full URL match
- **origin** – same protocol and host
- **origin+path** – same origin plus pathname
- **includes** – requested URL substring appears in tab URL

The caller specifies the desired match behavior via `options.match`.

### Step 3: Reuse or Create

Per the implementation in **[`nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/nav.ts) lines [182-209]`**:

| Condition | Action | Returned Flag |
|-----------|--------|-------------|
| Matching tab found | `switchTab(targetId)`, optionally `waitForDocumentLoad()` | `reused: true` |
| No match | `newTab(url)`, optionally wait for load | `reused: false` |

Both paths respect `wait`, `timeout`, and `settle` parameters for load-state control.

```javascript
// Open a new tab or reuse an existing one, then wait for the page to settle
const tab = await browser.openOrReuseTab('https://example.com', {
  match: 'origin',
  wait: true,
  settle: 500,   // extra pause after load
});
console.log(`Using tab ${tab.targetId}, reused: ${tab.reused}`);

```

## How ensureRealTab Guarantees a Usable Page

Agents sometimes initialize on internal pages (blank new-tab pages, extension backgrounds, or `chrome://` URLs). The `ensureRealTab` function at **[`nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/nav.ts) lines [236-253]** guarantees the active session points at a real user-navigable page.

### Operational Logic

1. **List non-internal tabs** via `listTabs({ includeChrome: false })`
2. **Check current tab** via `currentTab()`—if already real, return immediately
3. **Switch if needed**—activate `tabs[0].targetId` via `switchTab()`
4. **Handle empty state**—return `null` when no real tabs exist

```javascript
// Ensure the current session is on a real page before performing actions
const realTab = await browser.ensureRealTab();
if (!realTab) throw new Error('No user‑visible tab available');
await browser.switchTab(realTab.targetId);

```

This defensive pattern prevents automation failures when Chrome launches with default internal pages or when previous navigation lands on an unusable state.

## Integration with the Browser Façade

The **[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)** file re-exports these functions as methods on the `browser` object:

- `browser.openOrReuseTab` – documented at line 814
- `browser.ensureRealTab` – paired visibility

The declarative API specification in **[`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts)** generates runtime help text, guiding agents toward high-level calls rather than direct CDP manipulation. Underneath, **[`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts)** manages the low-level transport and session state that powers all tab operations.

## Summary

- **`openOrReuseTab`** implements intelligent tab deduplication with configurable URL matching and load-state waiting
- **`ensureRealTab`** provides a defensive guard that swaps from internal pages to real user content
- Both functions live in **[`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts)** and filter internal URLs using `INTERNAL_URL_PREFIXES`
- The **helpers.ts** façade exposes these through `browser.*` methods with full documentation support
- Optional parameters (`match`, `wait`, `settle`, `timeout`) give agents fine-grained control without CDP complexity

## Frequently Asked Questions

### What happens if openOrReuseTab finds multiple matching tabs?

The function uses the first match returned by `tabMatchesUrl`. The matching order follows the array sequence from `listTabs`, which reflects Chrome's internal tab ordering. For deterministic behavior, use stricter `match` values like `'exact'` rather than `'includes'`.

### Can ensureRealTab create a new tab if none exist?

No. `ensureRealTab` only switches to existing real tabs or returns `null`. It never creates tabs—use `openOrReuseTab` or `newTab` explicitly when you need to guarantee a tab exists.

### How does ego-browser distinguish internal from real tabs?

The `INTERNAL_URL_PREFIXES` array in [`nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/nav.ts) filters URLs starting with schemes like `chrome://`, `devtools://`, `chrome-extension://`, and Chrome's internal `about:` variants. The `includeChrome` parameter overrides this filtering when agents specifically need internal tab visibility.

### What is the performance cost of tab matching in openOrReuseTab?

The overhead is minimal: one `listTabs` CDP call plus synchronous URL string comparisons. In typical scenarios with under 50 tabs, this completes in single-digit milliseconds. The `settle` parameter adds intentional delay for page stability, not for the matching operation itself.