# How to Evaluate JavaScript in the Browser Context Using ego-browser

> Evaluate JavaScript in the browser context using ego-browser. Leverage evaluate() or js() helpers with the Chrome DevTools Protocol for seamless execution.

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

---

**Use the `evaluate()` or `js()` helpers exported from [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) to execute arbitrary JavaScript via the Chrome DevTools Protocol `Runtime.evaluate` method inside the controlled Chromium instance.**

The `ego-browser` package within the citrolabs/ego-lite repository provides AI agents with direct access to the browser runtime through a secure evaluation layer. By wrapping the Chrome DevTools Protocol (CDP), the system enables agents to evaluate JavaScript in the browser context using the utilities defined in [`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts). This architecture allows seamless querying of DOM state, execution of async operations, and interaction with web APIs using native JavaScript syntax.

## CDP Evaluation Architecture in src/cdp-eval.ts

The core evaluation engine resides in [[`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/cdp-eval.ts). This module exports the `evaluate()` function, which constructs CDP `Runtime.evaluate` payloads and manages bidirectional communication with the embedded browser.

When invoked, `evaluate()` sends a JSON payload structured as follows:

```json
{
  "method": "Runtime.evaluate",
  "params": {
    "expression": "<your_code>",
    "awaitPromise": true,
    "returnByValue": true,
    "userGesture": true
  }
}

```

The function resolves with the complete CDP response, including the `result` object containing the value, type, and object ID, along with any `exceptionDetails` if the script threw an error.

## The Helper Functions: evaluate() vs js()

The system exposes two distinct interfaces for JavaScript execution, both re-exported from [[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts).

### evaluate(): Raw CDP Access

Use `evaluate(expr: string, opts?)` when you need the full CDP response or detailed error information. This function returns the raw result from the browser's runtime, including metadata like object references and exception details.

### js(): Convenience Wrapper

The `js(expr: string)` helper simplifies common use cases by automatically extracting `result.value` from the CDP response. It wraps top-level return statements in an IIFE, allowing concise syntax like `js('document.title')`. If evaluation fails, it throws an `ElementResolutionError` with the browser-side exception details.

## Automatic Context Injection via helperContext()

Agent scripts do not require manual imports to access these utilities. The `helperContext()` function in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) automatically injects `evaluate` and `js` into the global scope of every executing script. This injection happens before script execution, ensuring seamless access to browser evaluation capabilities without `require` or `import` statements.

## Evaluating JavaScript: Code Examples

### Querying DOM Properties

Retrieve page state using the simplified `js()` helper:

```javascript
const pageTitle = await js('document.title');
const pageUrl = await js('window.location.href');
const elementCount = await js('document.querySelectorAll("div").length');

```

### Executing Async Operations

Perform asynchronous work by passing promises to `evaluate()`:

```javascript
const response = await evaluate(`
  fetch('https://api.example.com/data')
    .then(r => r.json())
    .then(data => data.items)
`);

console.log('Items:', response.result.value);

```

### Error Handling Patterns

Catch browser-side exceptions using standard try-catch blocks:

```javascript
try {
  await js('undefinedVariable.dangerousMethod()');
} catch (err) {
  console.error('Script failed:', err.message);
}

```

## Internal Usage in Driver Modules

The evaluation helpers power the entire browser automation stack. The driver modules utilize these functions for low-level browser interactions.

For instance, [[`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/pointer.ts) invokes `evaluate()` to calculate element bounding boxes before simulating mouse events. [[`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/nav.ts) uses these helpers to verify navigation completion and inspect `window.location` changes after redirects. Additionally, [[`src/driver/observe.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/observe.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/observe.ts) relies on evaluation to capture page state and DOM snapshots during observation tasks.

## Summary

- **Core evaluation logic** is implemented in [`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts), wrapping CDP `Runtime.evaluate` with `awaitPromise`, `returnByValue`, and `userGesture` flags.
- **Two interfaces** are available: `evaluate()` for raw protocol access and `js()` for simplified value extraction with automatic IIFE wrapping.
- **Global injection** via `helperContext()` in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) makes these functions available to all agent scripts without imports.
- **Driver integration** means [`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts), [`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts), and [`src/driver/observe.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/observe.ts) all depend on these helpers for element interaction and state inspection.
- **Built-in error handling** converts CDP exceptions into catchable JavaScript errors via `ElementResolutionError`.

## Frequently Asked Questions

### What is the difference between evaluate() and js() in ego-browser?

`evaluate()` returns the complete Chrome DevTools Protocol response object, including `result.objectId`, `result.value`, and `exceptionDetails`. The `js()` helper extracts only the `result.value` field and automatically wraps expressions in an IIFE, making it ideal for quick property lookups. Use `evaluate()` when you need full metadata or custom handling of CDP responses.

### Can I execute asynchronous JavaScript using ego-browser?

Yes. The `evaluate()` function sets `awaitPromise: true` by default, allowing you to pass promises and async functions. The browser waits for the promise to resolve before returning the result, enabling HTTP requests and other async operations within the evaluation context.

### How does ego-browser handle JavaScript errors during evaluation?

When browser execution throws an exception, `evaluate()` returns the error details in the `exceptionDetails` field. The `js()` wrapper detects these cases and throws an `ElementResolutionError` containing the message and stack trace from the browser context, allowing your agent code to handle failures gracefully.

### Are the evaluation helpers available automatically in agent scripts?

Yes. The `helperContext()` function in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) injects both `evaluate()` and `js()` into the global scope before script execution. You can call these functions directly without importing them, as the ego-browser runtime prepares the execution environment with these utilities pre-loaded.