A stealth-enhanced fork of Lightpanda Browser — the headless browser built from scratch for AI agents and automation.
Chrome fingerprint spoofing, Canvas 2D rendering, Web Audio API spoofing, and bot detection bypass. Written in Zig.
StealthPanda adds stealth capabilities on top of Lightpanda's fast, lightweight headless browser:
--stealthmode — spoofs a Chrome 131 fingerprint in HTTP headers and JS APIs (navigator.userAgent,navigator.plugins,window.chrome, etc.)- Canvas 2D software renderer — real pixel buffer with fillRect, fillText, path drawing, arc, toDataURL, toBlob — produces realistic canvas fingerprints that pass bot detection
- Web Audio API fingerprint spoofing — AudioContext, OfflineAudioContext, OscillatorNode, DynamicsCompressorNode, GainNode, AnalyserNode, AudioBufferSourceNode — generates deterministic audio fingerprints that match real Chrome output
- Font rasterization — stb_truetype integration with embedded Liberation Sans for authentic text rendering
- Fingerprint noise — per-session pixel variation so canvas hashes are unique across runs
- Navigator spoofing — platform, languages, hardwareConcurrency, deviceMemory, plugins, mimeTypes all match Chrome 131 on the target OS
- PluginArray & MimeTypeArray — 5 PDF plugins with proper circular references (MimeType → Plugin back-ref via
@fieldParentPtr), comptime-initialized for zero runtime overhead - 13/13 bot detection checks pass — tested against sannysoft fpScanner, intoli headless detection, and selenium/phantom markers
- 396 tests passing — full test suite green on CI
Everything else comes from upstream Lightpanda:
- Javascript execution via V8
- Support of Web APIs (partial, WIP)
- Compatible with Playwright1, Puppeteer, chromedp through CDP
- Ultra-low memory footprint (9x less than Chrome)
- Exceptionally fast execution (11x faster than Chrome)
- Instant startup
Install from releases
Download the latest binary from StealthPanda releases for Linux x86_64 and macOS aarch64.
For Linux
curl -L -o stealthpanda https://github.com/evan108108/StealthPanda/releases/latest/download/stealthpanda-x86_64-linux && \
chmod a+x ./stealthpandaFor macOS
curl -L -o stealthpanda https://github.com/evan108108/StealthPanda/releases/latest/download/stealthpanda-aarch64-macos && \
chmod a+x ./stealthpandaFor Windows + WSL2
The Lightpanda browser is compatible to run on windows inside WSL. Follow the Linux instruction for installation from a WSL terminal. It is recommended to install clients like Puppeteer on the Windows host.
Install from Docker
Lightpanda provides official Docker
images for both Linux amd64 and
arm64 architectures.
The following command fetches the Docker image and starts a new container exposing Lightpanda's CDP server on port 9222.
docker run -d --name lightpanda -p 9222:9222 lightpanda/browser:nightly./lightpanda fetch --obey-robots --log-format pretty --log-level info https://demo-browser.lightpanda.io/campfire-commerce/Use --stealth to spoof a Chrome 131 browser fingerprint. This overrides the User-Agent in both HTTP headers and JS APIs (navigator.userAgent, navigator.plugins, window.chrome, etc.), enables a Canvas 2D software renderer for realistic toDataURL() fingerprints, and provides Web Audio API spoofing for audio-based fingerprint checks.
./lightpanda fetch --stealth --dump html https://example.comINFO telemetry : telemetry status . . . . . . . . . . . . . [+0ms]
disabled = false
INFO page : navigate . . . . . . . . . . . . . . . . . . . . [+6ms]
url = https://demo-browser.lightpanda.io/campfire-commerce/
method = GET
reason = address_bar
body = false
req_id = 1
INFO browser : executing script . . . . . . . . . . . . . . [+118ms]
src = https://demo-browser.lightpanda.io/campfire-commerce/script.js
kind = javascript
cacheable = true
INFO http : request complete . . . . . . . . . . . . . . . . [+140ms]
source = xhr
url = https://demo-browser.lightpanda.io/campfire-commerce/json/product.json
status = 200
len = 4770
INFO http : request complete . . . . . . . . . . . . . . . . [+141ms]
source = fetch
url = https://demo-browser.lightpanda.io/campfire-commerce/json/reviews.json
status = 200
len = 1615
<!DOCTYPE html>./lightpanda serve --obey-robots --log-format pretty --log-level info --host 127.0.0.1 --port 9222INFO telemetry : telemetry status . . . . . . . . . . . . . [+0ms]
disabled = false
INFO app : server running . . . . . . . . . . . . . . . . . [+0ms]
address = 127.0.0.1:9222Once the CDP server started, you can run a Puppeteer script by configuring the
browserWSEndpoint.
'use strict'
import puppeteer from 'puppeteer-core';
// use browserWSEndpoint to pass the Lightpanda's CDP server address.
const browser = await puppeteer.connect({
browserWSEndpoint: "ws://127.0.0.1:9222",
});
// The rest of your script remains the same.
const context = await browser.createBrowserContext();
const page = await context.newPage();
// Dump all the links from the page.
await page.goto('https://demo-browser.lightpanda.io/amiibo/', {waitUntil: "networkidle0"});
const links = await page.evaluate(() => {
return Array.from(document.querySelectorAll('a')).map(row => {
return row.getAttribute('href');
});
});
console.log(links);
await page.close();
await context.close();
await browser.disconnect();By default, Lightpanda collects and sends usage telemetry. This can be disabled by setting an environment variable LIGHTPANDA_DISABLE_TELEMETRY=true. You can read Lightpanda's privacy policy at: https://lightpanda.io/privacy-policy.
Lightpanda is in Beta and currently a work in progress. Stability and coverage are improving and many websites now work. You may still encounter errors or crashes. Please open an issue with specifics if so.
Here are the key features we have implemented:
- CORS #2015
- HTTP loader (Libcurl)
- HTML parser (html5ever)
- DOM tree
- Javascript support (v8)
- DOM APIs
- Ajax
- XHR API
- Fetch API
- DOM dump
- CDP/websockets server
- Click
- Input form
- Cookies
- Custom HTTP headers
- Proxy support
- Network interception
- Respect
robots.txtwith option--obey-robots - Stealth mode with
--stealth(spoof Chrome fingerprint in HTTP headers and JS APIs) - Canvas 2D software renderer (fillRect, fillText, toDataURL, toBlob, path drawing, font rasterization)
- Web Audio API spoofing (AudioContext, OfflineAudioContext, OscillatorNode, DynamicsCompressorNode, GainNode, AnalyserNode)
- Navigator fingerprint spoofing (platform, languages, plugins, mimeTypes, deviceMemory, hardwareConcurrency)
NOTE: There are hundreds of Web APIs. Developing a browser (even just for headless mode) is a huge task. Coverage will increase over time.
Lightpanda is written with Zig 0.15.2. You have to
install it with the right version in order to build the project.
Lightpanda also depends on v8, Libcurl and html5ever.
To be able to build the v8 engine, you have to install some libs:
For Debian/Ubuntu based Linux:
sudo apt install xz-utils ca-certificates \
pkg-config libglib2.0-dev \
clang make curl git
You also need to install Rust.
For systems with Nix, you can use the devShell:
nix develop
For MacOS, you need cmake and Rust.
brew install cmake
You an build the entire browser with make build or make build-dev for debug
env.
But you can directly use the zig command: zig build run.
Lighpanda uses v8 snapshot. By default, it is created on startup but you can embed it by using the following commands:
Generate the snapshot.
zig build snapshot_creator -- src/snapshot.bin
Build using the snapshot binary.
zig build -Dsnapshot_path=../../snapshot.bin
See #1279 for more details.
You can test Lightpanda by running make test.
To run end to end tests, you need to clone the demo
repository into ../demo dir.
You have to install the demo's node requirements
You also need to install Go > v1.24.
make end2end
Lightpanda is tested against the standardized Web Platform Tests.
We use a fork including a custom
testharnessreport.js.
For reference, you can easily execute a WPT test case with your browser via wpt.live.
To run the test, you must clone the repository, configure the custom hosts and generate the
MANIFEST.json file.
Clone the repository with the fork branch.
git clone -b fork --depth=1 git@github.com:lightpanda-io/wpt.git
Enter into the wpt/ dir.
Install custom domains in your /etc/hosts
./wpt make-hosts-file | sudo tee -a /etc/hosts
Generate MANIFEST.json
./wpt manifest
Use the WPT's setup guide for details.
An external Go runner is provided by
github.com/lightpanda-io/demo/
repository, located into wptrunner/ dir.
You need to clone the project first.
First start the WPT's HTTP server from your wpt/ clone dir.
./wpt serve
Run a Lightpanda browser
zig build run -- --insecure-disable-tls-host-verification
Then you can start the wptrunner from the Demo's clone dir:
cd wptrunner && go run .
Or one specific test:
cd wptrunner && go run . Node-childNodes.html
wptrunner command accepts --summary and --json options modifying output.
Also --concurrency define the concurrency limit.
releaseFast mode to make tests faster.
zig build -Doptimize=ReleaseFast run
Lightpanda accepts pull requests through GitHub.
You have to sign our CLA during the pull request process otherwise we're not able to accept your contributions.
In the good old days, scraping a webpage was as easy as making an HTTP request, cURL-like. It’s not possible anymore, because Javascript is everywhere, like it or not:
- Ajax, Single Page App, infinite loading, “click to display”, instant search, etc.
- JS web frameworks: React, Vue, Angular & others
If we need Javascript, why not use a real web browser? Take a huge desktop application, hack it, and run it on the server. Hundreds or thousands of instances of Chrome if you use it at scale. Are you sure it’s such a good idea?
- Heavy on RAM and CPU, expensive to run
- Hard to package, deploy and maintain at scale
- Bloated, lots of features are not useful in headless usage
If we want both Javascript and performance in a true headless browser, we need to start from scratch. Not another iteration of Chromium, really from a blank page. Crazy right? But that’s what we did:
- Not based on Chromium, Blink or WebKit
- Low-level system programming language (Zig) with optimisations in mind
- Opinionated: without graphical rendering
Footnotes
-
Playwright support disclaimer: Due to the nature of Playwright, a script that works with the current version of the browser may not function correctly with a future version. See upstream note for details. ↩