# serverFetch vs browserFetch in ego-lite: HTTP Request Handling Guide

> Understand serverFetch vs browserFetch in ego-lite for efficient HTTP request handling. Learn how to execute requests from Node.js or your browser context.

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

---

**`serverFetch` executes HTTP requests from the Node.js host process, while `browserFetch` runs requests inside the active browser tab, inheriting the page's authentication state, cookies, and origin constraints.**

The ego-lite framework (`citrolabs/ego-lite`) provides a unified fetch façade that exposes two distinct HTTP request strategies through `fetch.server` and `fetch.browser`. Understanding the difference between `serverFetch` and `browserFetch` is essential for writing agents that interact correctly with external APIs versus authenticated web applications.

## Execution Context: Node.js vs Browser Page

The fundamental difference between these methods lies in where the HTTP request physically executes.

### Server-Side Execution with serverFetch

`serverFetch` runs **inside the Node.js process** that hosts the ego-lite runtime. According to the implementation in [[`src/http.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/http.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/http.ts#L11-L27), this method uses Node's global `fetch` to perform requests directly from the server environment. Because it operates outside the browser sandbox, `serverFetch` has no access to the active page's cookies, session storage, or origin policies.

### Browser-Side Execution with browserFetch

`browserFetch` executes **within the active browser tab** that the agent controls. As implemented in [[`src/http.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/http.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/http.ts#L35-L52), this method sends a payload to the browser via the `evaluate` helper (defined 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)), creating an async IIFE that runs `fetch` inside the page's JavaScript environment. This allows the request to inherit the page's authentication headers, CSRF tokens, and same-origin policies.

## Implementation and Technical Differences

### Request Headers and User-Agent

**serverFetch** merges caller-provided headers with a default **`User-Agent: Mozilla/5.0`** to emulate browser requests. This prevents basic bot detection while maintaining server-side execution.

**browserFetch** uses the page's native `fetch` implementation, automatically including any headers the browser would normally send—including cookies, `Accept` headers, and authentication tokens bound to the current domain.

### URL Resolution Behavior

`serverFetch` requires **absolute URLs** because the Node environment has no concept of a current page context. Attempting to pass relative URLs will result in resolution errors.

`browserFetch` accepts **relative URLs** (e.g., `/api/user`), resolving them against the current page's URL exactly as standard browser navigation would. This mirrors normal web application behavior.

### Timeout Handling Mechanisms

The timeout implementations differ between environments. `serverFetch` uses `AbortSignal.timeout` (available in Node.js ≥16), while `browserFetch` implements a manual timeout mechanism using `setTimeout` paired with an `AbortController` to cancel the in-page request.

## Practical Code Examples

Use `fetch.server` when retrieving external resources unrelated to the current page:

```typescript
// Server-side fetch: Download external HTML or API data
const html = await fetch.server('https://example.com/data', {
  timeout: 10,  // seconds
  headers: { 'Accept': 'text/html' }
});
// Returns raw response body as string

```

Use `fetch.browser` when the request must execute as the logged-in user:

```typescript
// Browser-side fetch: Call authenticated endpoints
const userData = await fetch.browser('/api/user/profile', {
  method: 'GET',
  headers: { 'Accept': 'application/json' },
  timeout: 5
});
// Inherits the page's cookies and authentication state

```

## Summary

- **serverFetch** operates in the Node.js host process using native `fetch`, requires absolute URLs, and adds a browser-like User-Agent header.
- **browserFetch** executes inside the controlled browser page via `evaluate`, supports relative URLs, and inherits the page's cookies and security context.
- Both methods throw errors for non-OK HTTP statuses and support configurable timeouts, though they use different abort mechanisms.
- The unified fetch façade is exposed through [[`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#L28-L31), with public signatures documented in [[`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/format.ts#L886-L925).

## Frequently Asked Questions

### When should I use serverFetch instead of browserFetch?

Use **serverFetch** when retrieving external resources that are not tied to the current page context, such as downloading files from third-party APIs or scraping remote HTML pages. Use **browserFetch** when the request must execute within the user's authenticated session, such as calling internal APIs that rely on cookies, CSRF tokens, or same-origin policies.

### Can browserFetch handle relative URLs?

Yes. Unlike `serverFetch`, which requires absolute URLs, `browserFetch` resolves relative URLs against the current page's location, matching standard browser behavior. This allows agents to interact with web applications using the same relative paths used by the application's frontend code.

### How does authentication differ between serverFetch and browserFetch?

`serverFetch` executes as a standalone Node.js process and cannot access the browser's cookie store or session storage. `browserFetch` runs inside the page's JavaScript context and automatically includes all browser-managed credentials, including HTTP-only cookies, bearer tokens, and CSRF headers required by the current origin.

### What timeout mechanisms do these methods use?

`serverFetch` leverages Node.js's native `AbortSignal.timeout` (Node ≥16) to cancel requests that exceed the specified duration. `browserFetch` implements a manual timeout using `setTimeout` combined with an `AbortController` to terminate the fetch operation within the browser page, ensuring compatibility with the browser's fetch implementation.