# Ego-Browser Snapshot vs Screenshot: Three Observation Methods Compared

> Compare ego browser snapshot snapshotRaw and screenshot observation methods. Learn when to use each for text DOM data or visual captures to improve your testing.

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

---

**Use `snapshot()` for plain text, `snapshotRaw()` for structured DOM data with element refs, and `screenshot()` for pixel-based visual captures.**

Ego-browser provides three distinct observation helpers that serve different automation needs. Understanding when to use `snapshot`, `snapshotRaw`, or `screenshot` in ego-browser ensures your agent receives the right data format for each task, whether parsing page content, interacting with specific elements, or performing visual verification.

## What snapshot() Returns in Ego-Browser

`snapshot()` provides the simplest interface for text extraction. It returns a plain string containing the page's readable content, with stable locators and action marks embedded by default.

In [`package/ego-browser/src/driver/observe.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/observe.ts), the implementation (lines 73-80) calls `snapshotRaw()` with preset options and extracts only the `content` field:

```javascript
// From observe.ts lines 73-80
async snapshot() {
  const result = await this.snapshotRaw({
    scope: "full_page",
    includeActionMarks: true,
    includeStableLocator: true,
  });
  return result.content;
}

```

This makes `snapshot()` ideal when you need clean text for language model prompts, search operations, or content analysis.

## What snapshotRaw() Returns in Ego-Browser

`snapshotRaw()` returns the complete **structured object** from the ego runtime, including metadata that `snapshot()` strips away.

The full return type includes:
- `content`: the textual page content
- `refs`: array of stable reference objects for element interaction
- Additional snapshot metadata

The implementation (lines 49-63 in [`observe.ts`](https://github.com/citrolabs/ego-lite/blob/main/observe.ts)) forwards directly to `browserEgo().snapshot` and handles error translation:

```javascript
// From observe.ts lines 49-63
async snapshotRaw(options: SnapshotOptions = {}) {
  const result = await browserEgo()
    .snapshot(options)
    .catch((err) => {
      throw new EgoError(
        `Failed to snapshot: ${err.message}`,
        "SNAPSHOT_ERROR"
      );
    });
  
  this.refMap = result.refs;
  return result;
}

```

Choose `snapshotRaw()` when you need to:
- Access element refs (`@N` syntax) for later interactions
- Customize which locators or marks to include
- Build custom processing pipelines on the raw snapshot structure

## What screenshot() Returns in Ego-Browser

`screenshot()` operates entirely differently from the snapshot methods. Instead of DOM traversal, it uses **Chrome DevTools Protocol (CDP)** to capture a bitmap image of the page.

The implementation (lines 97-139 in [`observe.ts`](https://github.com/citrolabs/ego-lite/blob/main/observe.ts)) builds CDP parameters, handles clipping regions, and manages file output:

```javascript
// Capturing a full-page screenshot
const path = await page.screenshot({ fullPage: true, path: './capture.png' });

// Capturing a specific region without file I/O
const clip = { x: 100, y: 200, width: 300, height: 80 };
const tempPath = await page.screenshot({ raw: true, clip });

```

Key characteristics of `screenshot()`:
- Returns a file path (or temporary path when `raw: true`)
- Produces PNG format only
- Supports `fullPage`, `clip`, and device-pixel-ratio options
- Generates no textual data or element refs

## Complete Comparison: snapshot vs snapshotRaw vs screenshot

| Method | Data Type | Data Source | Best For |
|--------|-----------|-------------|----------|
| `snapshot()` | Plain `string` | DOM snapshot via ego runtime | LLM prompts, text extraction, simple parsing |
| `snapshotRaw()` | Structured object with `content`, `refs`, metadata | DOM snapshot via ego runtime | Element interaction refs, custom snapshot processing |
| `screenshot()` | File path to PNG | CDP `Page.captureScreenshot` | Visual verification, OCR, debugging, image-based workflows |

## Code Examples for Each Observation Method

### Extracting Clean Text

```javascript
// Use snapshot() for minimal, readable output
const pageText = await page.snapshot();
console.log('Extracted content:', pageText.substring(0, 500));

```

### Working with Element References

```javascript
// Use snapshotRaw() when you need to interact with specific elements
const raw = await page.snapshotRaw({
  scope: "full_page",
  includeActionMarks: true
});

// Access the refs array for element targeting
console.log(`Found ${raw.refs.length} interactive elements`);

// Later use @N syntax to click a specific element
await page.click('@3');

```

### Visual Capture Scenarios

```javascript
// Full page documentation screenshot
await page.screenshot({ 
  fullPage: true, 
  path: './docs-page.png' 
});

// Clipped region for a specific component
await page.screenshot({
  path: './button.png',
  clip: { x: 50, y: 100, width: 200, height: 60 }
});

// Raw capture for network transmission
const tempPath = await page.screenshot({ raw: true });
const imageBuffer = fs.readFileSync(tempPath);

```

## Source File Reference

All three observation methods are implemented in [`package/ego-browser/src/driver/observe.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/observe.ts) and re-exported through [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) (lines 84-90) for the public `page` API:

| File | Purpose |
|------|---------|
| [`src/driver/observe.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/observe.ts) | Core implementations of `snapshot`, `snapshotRaw`, `screenshot` |
| [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) | Public API façade exposing methods on `page` object |
| [`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts) | Helper signature definitions for generated documentation |

## Summary

- **Use `snapshot()`** when you need plain text for language model consumption or simple content analysis
- **Use `snapshotRaw()`** when you require structured data with element references (`@N` syntax) for interactive automation
- **Use `screenshot()`** when pixel-perfect visual capture is required for OCR, debugging, or image-based verification workflows

Each method serves a distinct purpose in the ego-browser observation architecture: the two snapshot variants leverage the ego runtime's DOM analysis capabilities, while screenshot bypasses that layer entirely for direct CDP image capture.

## Frequently Asked Questions

### Can I get both text and visual data in a single call?

No. `snapshot`/`snapshotRaw` and `screenshot` use entirely different data sources—the ego runtime's DOM walker versus CDP's rendering engine. You must make separate calls if your workflow requires both textual structure and visual representation.

### What format does screenshot() return when raw: true is set?

Even with `raw: true`, `screenshot()` returns a temporary file path, not a buffer. The implementation in [`observe.ts`](https://github.com/citrolabs/ego-lite/blob/main/observe.ts) always writes to disk; you must read the file yourself. The `raw` option primarily indicates whether to use a temporary path versus your specified `path` parameter.

### How do element references (@N) work with snapshotRaw()?

The ego runtime assigns numeric identifiers to interactive elements during DOM traversal. These appear in the `refs` array with their corresponding `@N` format strings. After calling `snapshotRaw()`, you can use these references in `page.click('@3')` or similar action methods—ego-browser maintains an internal ref map for lookup.

### Which method is fastest for large pages?

`snapshot()` is marginally faster than `snapshotRaw()` because it extracts only the `content` string. `screenshot()` performance depends on page complexity and capture dimensions, as it must render and encode a PNG. For text-only extraction, avoid `screenshot()` entirely—it performs no DOM analysis and returns no textual data.