Lightpanda — Headless Browser for AI & Automation Skill by ara.so — Daily 2026 Skills collection Lightpanda is a headless browser built from scratch in Zig, designed for AI agents, web scraping, and automation. It uses 9x less memory and runs 11x faster than Chrome headless. Key facts: Not based on Chromium, Blink, or WebKit — clean-slate Zig implementation JavaScript execution via V8 engine CDP (Chrome DevTools Protocol) compatible — works with Playwright, Puppeteer, chromedp Respects robots.txt via --obey_robots flag Beta status, actively developed License: AGPL-3.0 Installation macOS (Apple Silicon) curl -L -o lightpanda https://github.com/lightpanda-io/browser/releases/download/nightly/lightpanda-aarch64-macos chmod a+x ./lightpanda Linux (x86_64) curl -L -o lightpanda https://github.com/lightpanda-io/browser/releases/download/nightly/lightpanda-x86_64-linux chmod a+x ./lightpanda Docker
Supports amd64 and arm64
docker
run
-d
--name
lightpanda
-p
9222
:9222 lightpanda/browser:nightly
CLI Usage
Fetch a URL (dump rendered HTML)
./lightpanda fetch
--obey_robots
--log_format
pretty
--log_level
info https://example.com
Start CDP Server
./lightpanda serve
--obey_robots
--log_format
pretty
--log_level
info
--host
127.0
.0.1
--port
9222
This launches a WebSocket-based CDP server for programmatic control.
CLI Flags
Flag
Description
--obey_robots
Respect robots.txt rules
--log_format pretty
Human-readable log output
--log_level info
Log verbosity:
debug
,
info
,
warn
,
error
--host 127.0.0.1
Bind address for CDP server
--port 9222
Port for CDP server
--insecure_disable_tls_host_verification
Disable TLS verification (testing only)
Playwright Integration
Start the CDP server, then connect Playwright to it:
import
{
chromium
}
from
'playwright-core'
;
const
browser
=
await
chromium
.
connectOverCDP
(
'http://127.0.0.1:9222'
)
;
const
context
=
await
browser
.
contexts
(
)
[
0
]
||
await
browser
.
newContext
(
)
;
const
page
=
await
context
.
newPage
(
)
;
await
page
.
goto
(
'https://example.com'
,
{
waitUntil
:
'networkidle'
}
)
;
const
title
=
await
page
.
title
(
)
;
const
content
=
await
page
.
content
(
)
;
console
.
log
(
Title:
${
title
}
)
;
console
.
log
(
HTML length:
${
content
.
length
}
)
;
await
browser
.
close
(
)
;
Puppeteer Integration
import
puppeteer
from
'puppeteer-core'
;
const
browser
=
await
puppeteer
.
connect
(
{
browserWSEndpoint
:
'ws://127.0.0.1:9222'
,
}
)
;
const
context
=
await
browser
.
createBrowserContext
(
)
;
const
page
=
await
context
.
newPage
(
)
;
await
page
.
goto
(
'https://example.com'
,
{
waitUntil
:
'networkidle0'
}
)
;
const
title
=
await
page
.
title
(
)
;
const
text
=
await
page
.
evaluate
(
(
)
=>
document
.
body
.
innerText
)
;
console
.
log
(
Title:
${
title
}
)
;
console
.
log
(
Body text:
${
text
.
substring
(
0
,
200
)
}
)
;
await
page
.
close
(
)
;
await
browser
.
close
(
)
;
Go (chromedp) Integration
package
main
import
(
"context"
"fmt"
"log"
"github.com/chromedp/chromedp"
)
func
main
(
)
{
allocCtx
,
cancel
:=
chromedp
.
NewRemoteAllocator
(
context
.
Background
(
)
,
"ws://127.0.0.1:9222"
)
defer
cancel
(
)
ctx
,
cancel
:=
chromedp
.
NewContext
(
allocCtx
)
defer
cancel
(
)
var
title
string
err
:=
chromedp
.
Run
(
ctx
,
chromedp
.
Navigate
(
"https://example.com"
)
,
chromedp
.
Title
(
&
title
)
,
)
if
err
!=
nil
{
log
.
Fatal
(
err
)
}
fmt
.
Println
(
"Title:"
,
title
)
}
Python Integration
import
asyncio
from
playwright
.
async_api
import
async_playwright
async
def
main
(
)
:
async
with
async_playwright
(
)
as
p
:
browser
=
await
p
.
chromium
.
connect_over_cdp
(
"http://127.0.0.1:9222"
)
context
=
browser
.
contexts
[
0
]
if
browser
.
contexts
else
await
browser
.
new_context
(
)
page
=
await
context
.
new_page
(
)
await
page
.
goto
(
"https://example.com"
,
wait_until
=
"networkidle"
)
title
=
await
page
.
title
(
)
content
=
await
page
.
content
(
)
print
(
f"Title:
{
title
}
"
)
print
(
f"HTML length:
{
len
(
content
)
}
"
)
await
browser
.
close
(
)
asyncio
.
run
(
main
(
)
)
Web Scraping Patterns
Batch Page Fetching
import
{
chromium
}
from
'playwright-core'
;
const
browser
=
await
chromium
.
connectOverCDP
(
'http://127.0.0.1:9222'
)
;
const
context
=
await
browser
.
newContext
(
)
;
const
urls
=
[
'https://example.com/page1'
,
'https://example.com/page2'
,
'https://example.com/page3'
,
]
;
for
(
const
url
of
urls
)
{
const
page
=
await
context
.
newPage
(
)
;
await
page
.
goto
(
url
,
{
waitUntil
:
'networkidle'
}
)
;
const
data
=
await
page
.
evaluate
(
(
)
=>
(
{
title
:
document
.
title
,
text
:
document
.
body
.
innerText
,
links
:
[
...
document
.
querySelectorAll
(
'a[href]'
)
]
.
map
(
a
=>
a
.
href
)
,
}
)
)
;
console
.
log
(
JSON
.
stringify
(
data
,
null
,
2
)
)
;
await
page
.
close
(
)
;
}
await
browser
.
close
(
)
;
Extract Structured Data
const
data
=
await
page
.
evaluate
(
(
)
=>
{
const
items
=
document
.
querySelectorAll
(
'.product-card'
)
;
return
[
...
items
]
.
map
(
item
=>
(
{
name
:
item
.
querySelector
(
'h2'
)
?.
textContent
?.
trim
(
)
,
price
:
item
.
querySelector
(
'.price'
)
?.
textContent
?.
trim
(
)
,
link
:
item
.
querySelector
(
'a'
)
?.
href
,
}
)
)
;
}
)
;
Docker Compose (with your app)
services
:
lightpanda
:
image
:
lightpanda/browser
:
nightly
ports
:
-
"9222:9222"
restart
:
unless
-
stopped
scraper
:
build
:
.
depends_on
:
-
lightpanda
environment
:
-
BROWSER_WS_ENDPOINT=ws
:
//lightpanda
:
9222
Supported Web APIs
Lightpanda supports (partial, expanding):
DOM tree manipulation and querying
JavaScript execution (V8)
XMLHttpRequest (XHR)
Fetch API
Cookie management
Network interception
Proxy support
Configuration
Environment Variable
Description
LIGHTPANDA_DISABLE_TELEMETRY
Set to
true
to opt out of usage metrics
Performance Comparison
Metric
Lightpanda
Chrome Headless
Memory
~9x less
Baseline
Speed
~11x faster
Baseline
Binary size
Small (Zig)
Large (Chromium)
Rendering
No visual rendering
Full rendering engine
When to Use Lightpanda
Use Lightpanda when:
Running AI agents that need to browse the web
Batch scraping at scale (memory/CPU savings matter)
Automating form submissions and data extraction
Running in containers where resources are limited
You need CDP compatibility but not full visual rendering
Use Chrome/Playwright instead when:
You need pixel-perfect screenshots or PDF generation
You need full Web API coverage (Lightpanda is still partial)
Visual regression testing
Testing browser-specific rendering behavior
Building from Source
Requires: Zig 0.15.2, Rust, CMake, system dependencies.
Ubuntu/Debian dependencies
sudo apt install xz-utils ca-certificates pkg-config libglib2.0-dev clang make curl
Build
git clone https://github.com/lightpanda-io/browser.git cd browser zig build
Optional: pre-build V8 snapshot for faster startup
zig build snapshot_creator -- src/snapshot.bin zig build -Dsnapshot_path = .. / .. /snapshot.bin Troubleshooting Connection refused on port 9222: Ensure ./lightpanda serve is running Check --host 0.0.0.0 if connecting from Docker/remote Playwright script breaks after update: Lightpanda is beta — Playwright's capability detection may behave differently across versions Pin your Lightpanda version or use nightly consistently Missing Web API support: Check the zig-js-runtime repo for current API coverage File issues at lightpanda-io/browser Links GitHub: https://github.com/lightpanda-io/browser Runtime APIs: https://github.com/lightpanda-io/zig-js-runtime