`snapshot()` vs `snapshotRaw()` in ego-lite: Key Differences and When to Use Each

snapshot() returns a plain string of rendered page content, while snapshotRaw() returns a structured object with the full payload including reference metadata.

When building browser automation with ego-lite, you'll need to capture the state of a web page. The library provides two distinct methods for this purpose. Both serve the same fundamental goal—taking a semantic snapshot of the page—but differ in what they return and how you should use them.

What snapshot() Returns

The snapshot() method gives you a ready-to-use string containing the rendered page content. This string includes semantic snapshot text, automatically-added action marks, and stable locators (refs) that agents can use to interact with the page.

In src/driver/observe.ts, the implementation is straightforward: it calls snapshotRaw() with default options and extracts only the content field.

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

Use snapshot() when you need a human-readable page dump—for example, when feeding the result directly to a language model or logging page state for debugging.

What snapshotRaw() Returns

The snapshotRaw() method returns the complete structured snapshot object. This includes not just the content string, but also the refs array and any additional metadata from the browser runtime.

As implemented in src/driver/observe.ts (lines 49-63), this method directly calls the browser runtime's ego.snapshot method, handles low-level errors, updates the internal reference map, and returns the entire result object:

// Returns: { content: string, refs: RefState[], ... }
const raw = await page.snapshotRaw();

Use snapshotRaw() when you need programmatic access to the snapshot's reference map—for instance, when building custom element resolution logic or manipulating the raw data before text extraction.

Side-by-Side Comparison

Aspect snapshot() snapshotRaw()
Return type string Structured object ({ content, refs, ... })
Default options scope: "full_page", includeActionMarks: true, includeStableLocator: true Configurable via parameter
Includes refs array No (only in rendered text) Yes (accessible as property)
Use case LLM input, logging, quick inspection Custom processing, element resolution, debugging refs

Practical Code Examples

Basic String Snapshot

const pageContent = await page.snapshot();
console.log(pageContent);
// Output: "Search results for 'ego-lite'\n[ref=1] Introduction\n[ref=2] Installation..."

Raw Structured Access

const rawSnapshot = await page.snapshotRaw();
console.log(rawSnapshot.content);  // Same string as snapshot()
console.log(rawSnapshot.refs);     // Array of reference objects

// Inspect individual refs for custom logic
for (const ref of rawSnapshot.refs) {
  console.log(`Element ${ref.id}: ${ref.tagName} at (${ref.x}, ${ref.y})`);
}

Where References Are Stored

The refs array returned by snapshotRaw() feeds into ego-lite's internal reference management system. In src/ref-state.ts, the library maintains a reference map that receives these refs. Later, src/element-resolver.ts shows how these snapshot refs are resolved back to actual DOM elements for interaction.

This matters because:

  • snapshot() renders refs into the text but doesn't expose them programmatically
  • snapshotRaw() lets you see and manipulate the ref data before any rendering happens

API Documentation Reference

The public API documentation in src/format.ts (lines 402-423) clarifies this distinction:

  • page.snapshot: "Return a semantic page snapshot with refs and stable locators"
  • page.snapshotRaw: "Return the raw structured snapshot object"

Both functions are exposed to user scripts through src/helpers.ts.

Summary

  • snapshot() is the convenience method—call it when you need a string and don't care about the underlying structure
  • snapshotRaw() is the power user's tool—call it when you need the full payload with reference data for custom processing
  • Both methods live in src/driver/observe.ts and share the same browser runtime foundation
  • The refs array from snapshotRaw() flows through src/ref-state.ts and resolves via src/element-resolver.ts

Choose snapshot() for simplicity, snapshotRaw() for control.

Frequently Asked Questions

Can I get the refs array after calling snapshot()?

No. Once you call snapshot(), the refs are rendered into the text as [ref=N] markers but the original array is discarded. If you need programmatic access to reference data, use snapshotRaw() instead.

Does snapshotRaw() support the same formatting options as snapshot()?

Yes, and more. Since snapshotRaw() accepts a configuration object, you can customize scope, action marks, and stable locators. snapshot() merely calls snapshotRaw() with hardcoded defaults and returns .content.

Which method is faster?

Both have identical performance characteristics—they execute the same browser runtime call. The negligible difference comes from snapshot() extracting one string property versus snapshotRaw() returning the full object.

When would I need to manipulate refs before rendering?

Common scenarios include: filtering out invisible elements, reordering refs by visual priority, attaching custom metadata to elements, or building domain-specific locators that don't match ego-lite's default stable locator generation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →