serverFetch vs browserFetch in ego-browser: Key Differences Explained
serverFetch executes HTTP requests from the Node.js host process while browserFetch runs requests inside the controlled browser page, inheriting cookies, authentication state, and same-origin policies.
The ego-browser package in the citrolabs/ego-lite repository exposes a unified fetch façade that abstracts two distinct HTTP strategies. Understanding the difference between serverFetch and browserFetch is essential for writing automation scripts that interact with both external APIs and authenticated web applications.
Execution Context and Architecture
Server-Side Requests with serverFetch
As implemented in ego-browser/src/http.ts (lines 11-27), serverFetch operates entirely within the Node.js runtime that hosts the ego-lite agent. It calls the native Node.js fetch implementation directly, making it suitable for retrieving resources that do not require the browser's session context. Because it runs server-side, it only accepts absolute URLs and has no access to the page's cookies or local storage.
Browser-Side Requests with browserFetch
Conversely, browserFetch (defined in ego-browser/src/http.ts, lines 35-52) executes code inside the active browser tab via the evaluate helper from src/cdp-eval.ts. This method creates an async IIFE within the page’s JavaScript context, allowing the request to inherit the page’s origin, CSRF tokens, and authentication cookies. It supports relative URLs, which resolve against the current page's location.
Source Code Implementation Details
Underlying these differences are distinct timeout mechanisms and header handling strategies:
-
serverFetch: Uses
AbortSignal.timeout(requires Node.js ≥ 16) for request cancellation. It merges caller-provided headers with a defaultUser-Agent: Mozilla/5.0to emulate browser requests, and validates that URLs are absolute. -
browserFetch: Implements manual timeout handling via
setTimeoutand anAbortControllerinjected into the page context. It relies on the browser's nativefetch, automatically including the page's default headers, cookies, and security policies.
The unified façade exposing both methods is defined in src/helpers.ts (lines 28-31), while public type signatures and comprehensive documentation reside in src/format.ts (lines 886-925).
Key Differences Comparison
| Feature | serverFetch | browserFetch |
|---|---|---|
| Execution Environment | Node.js host process | Active browser page via CDP |
| URL Support | Absolute URLs only | Absolute and relative URLs |
| Authentication State | No inherited cookies or sessions | Full cookie and session inheritance |
| User-Agent Handling | Injected Mozilla/5.0 |
Native browser header |
| Timeout Mechanism | AbortSignal.timeout |
AbortController with setTimeout |
| Error Handling | Throws on non-OK HTTP statuses | Throws on non-OK HTTP statuses |
Practical Code Examples
Use serverFetch when retrieving external resources from third-party APIs that do not require session authentication:
// Server-side: Fetch external data with custom timeout
const html = await fetch.server('https://api.example.com/data', {
timeout: 10,
headers: { 'Accept': 'application/json' }
});
Use browserFetch for authenticated endpoints that rely on the current page's security context:
// Browser-side: Call API using current page's cookies and origin
const userData = await fetch.browser('/api/user/profile', {
method: 'GET',
headers: { 'Accept': 'application/json' },
timeout: 5
});
// Relative URL '/api/user/profile' resolves against window.location
When to Use Each Method
Choose serverFetch for operations such as downloading static assets from CDNs, scraping public HTML pages, or calling external REST APIs where browser session state is irrelevant. This avoids the overhead of browser execution and bypasses Content Security Policy restrictions that might block requests within the page context.
Choose browserFetch when interacting with endpoints protected by CSRF tokens, session cookies, or strict same-origin policies. This method executes requests as if the user triggered them manually, preserving the authentication and security context of the active tab.
Summary
- serverFetch runs in Node.js via
ego-browser/src/http.ts(lines 11-27), requires absolute URLs, and usesAbortSignal.timeout - browserFetch executes inside the browser page via
src/cdp-eval.ts, inherits cookies, resolves relative URLs, and usesAbortController - Both methods throw errors for non-OK HTTP statuses and are exposed through the unified façade in
src/helpers.ts - serverFetch adds a default Mozilla User-Agent; browserFetch uses native browser headers
Frequently Asked Questions
Can browserFetch access cookies from the current browser session?
Yes. Because browserFetch executes via the evaluate helper in src/cdp-eval.ts, it runs the fetch call within the page's JavaScript context. This means it automatically includes all cookies, authentication headers, and browser state associated with the current origin, behaving exactly like a user-initiated request.
Why does serverFetch require absolute URLs while browserFetch supports relative paths?
The serverFetch implementation in ego-browser/src/http.ts runs in the Node.js environment, which has no concept of a "current page" or base URL for resolution. Therefore, it cannot resolve relative paths. browserFetch executes inside the browser where the native fetch resolves relative paths against window.location.
Which method should I use for downloading large files?
Use serverFetch for large external downloads to avoid consuming browser memory and to bypass potential Content Security Policy restrictions within the page. serverFetch streams data directly through the Node.js process, while browserFetch executes within the browser context and inherits all page-level limitations.
Does serverFetch support custom headers?
Yes. According to the implementation in ego-browser/src/http.ts, serverFetch merges caller-provided headers with its default User-Agent. You can pass any valid headers object to override defaults or add API keys for external services, though the request will not include any cookies from the browser session.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →