Lightpanda Fetch Mode vs Serve Mode: Understanding the Difference
Fetch mode performs a single-shot page retrieval with optional content dumping to stdout or file, while serve mode launches a persistent Chrome DevTools Protocol (CDP) server that accepts remote WebSocket connections for interactive browser automation.
Lightpanda is a lightweight, headless browser written in Zig designed for high-performance web automation. The src/Config.zig file defines distinct run modes that determine how the browser initializes and executes, with fetch and serve representing two fundamentally different architectural approaches. Understanding these modes ensures you select the appropriate method for one-off data extraction versus long-running automation workflows.
Configuration Architecture
The behavioral differences between fetch and serve mode originate in their respective configuration structures within src/Config.zig.
Fetch Mode Configuration
Config.Fetch (defined at lines 220–227) contains the target URL, dump format options (HTML, markdown, semantic tree), and a shared Common configuration block. This structure supports the single-execution pattern where the process terminates immediately after retrieving and optionally serializing the document.
Serve Mode Configuration
Config.Serve (defined at lines 199–206) specifies network parameters including host, port, timeout settings, and connection limits alongside the Common block. Unlike fetch mode, this configuration supports persistent socket listening and multi-session management required for remote protocol support.
Operational Implementation
The entry points in src/main.zig (around lines 84–105) dispatch to entirely different execution paths based on the selected mode.
Fetch Mode: Single-Shot Execution
When invoked with case .fetch, the application constructs a FetchOpts structure and calls lp.fetch(app, url, fetch_opts). The core implementation in src/lightpanda.zig (lines 52–63 and 104–136) performs the following sequence:
- Instantiates a
Browserobject - Navigates to the specified URL
- Waits for page stabilization
- Serializes the document or semantic tree if dump mode is enabled
- Writes output to the configured writer (stdout or file)
- Terminates the process
This mode is ideal for static-site generation, one-off page extraction, or pipeline debugging where no ongoing interaction is required.
Serve Mode: Persistent CDP Server
When invoked with case .serve, the main.zig branch (lines 84–102) initializes a lp.Server instance that implements the Chrome DevTools Protocol. The implementation in src/Server.zig establishes a listening socket and enters a network loop that:
- Accepts incoming WebSocket connections
- Dispatches CDP messages to underlying
Browsersessions - Maintains process longevity until interrupted (SIGTERM, Ctrl-C)
This architecture enables external tools like Puppeteer, Playwright, or chromedp to connect via ws://host:port and control multiple pages programmatically across extended sessions.
Practical Usage Examples
Running Fetch Mode
Execute a one-time page capture with content dumping:
# Dump rendered HTML to file
./lightpanda fetch --dump html https://example.com > page.html
# Extract markdown representation
./lightpanda fetch --dump markdown https://example.com > page.md
# Output JSON-encoded semantic tree to stdout
./lightpanda fetch --dump semantic_tree https://example.com
Running Serve Mode
Start the CDP server for remote automation:
# Default binding (127.0.0.1:9222)
./lightpanda serve
# Custom network interface and port
./lightpanda serve --host 0.0.0.0 --port 8080
Connect programmatically using Puppeteer:
const puppeteer = require('puppeteer-core');
const browser = await puppeteer.connect({
browserWSEndpoint: 'ws://127.0.0.1:9222',
});
const page = await browser.newPage();
await page.goto('https://example.com');
Summary
- Fetch mode uses
Config.Fetchto execute a single navigation, dump content vialp.fetch()insrc/lightpanda.zig, and exit immediately. - Serve mode uses
Config.Serveto instantiate a persistent CDP server viasrc/Server.zig, maintaining WebSocket connections for remote automation. - Fetch mode directs output to files or stdout, while serve mode communicates exclusively through CDP protocol messages.
- Fetch mode terminates after page retrieval; serve mode runs indefinitely until signal interruption.
Frequently Asked Questions
When should I use fetch mode instead of serve mode?
Use fetch mode for batch processing, static-site generation, or CI/CD pipelines where you need to extract content from specific URLs without maintaining a persistent browser instance. Use serve mode when integrating with existing automation frameworks like Puppeteer or Playwright that require interactive session management across multiple page navigations.
Can fetch mode handle JavaScript-heavy applications?
Yes, the lp.fetch() implementation in src/lightpanda.zig instantiates a full Browser instance and waits for page stabilization before dumping, ensuring JavaScript execution completes. However, unlike serve mode, you cannot interact with the page after initial load or perform multi-step workflows.
What network protocols does serve mode support?
Serve mode implements the Chrome DevTools Protocol (CDP) over WebSocket connections, as defined in src/Server.zig. This allows compatibility with any tool supporting CDP, including Puppeteer, Playwright, and Selenium ChromeDriver, without requiring proprietary extensions.
How do I limit concurrent connections in serve mode?
The Config.Serve structure in src/Config.zig (lines 199–206) includes connection limit parameters that control the maximum number of simultaneous WebSocket sessions. Configure these via command-line flags when starting the server to prevent resource exhaustion during high-concurrency automation scenarios.
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 →