lightpanda-browser

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Lightpanda — Headless Browser for AI & Automation

Lightpanda — 面向AI与自动化的无头浏览器

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
来自ara.so的技能指南 — 2026每日技能合集
Lightpanda是一款完全基于Zig从零构建的无头浏览器,专为AI Agent、网页抓取和自动化场景设计。它的内存占用比Chrome无头模式少9倍,运行速度快11倍。
核心特性:
  • 不基于Chromium、Blink或WebKit——完全基于Zig从零实现
  • 通过V8引擎执行JavaScript
  • 兼容CDP(Chrome DevTools Protocol)——可与Playwright、Puppeteer、chromedp配合使用
  • 通过
    --obey_robots
    参数遵循
    robots.txt
    规则
  • 处于Beta阶段,正在积极开发中
  • 许可证:AGPL-3.0

Installation

安装

macOS (Apple Silicon)

macOS(Apple Silicon)

bash
curl -L -o lightpanda https://github.com/lightpanda-io/browser/releases/download/nightly/lightpanda-aarch64-macos
chmod a+x ./lightpanda
bash
curl -L -o lightpanda https://github.com/lightpanda-io/browser/releases/download/nightly/lightpanda-aarch64-macos
chmod a+x ./lightpanda

Linux (x86_64)

Linux(x86_64)

bash
curl -L -o lightpanda https://github.com/lightpanda-io/browser/releases/download/nightly/lightpanda-x86_64-linux
chmod a+x ./lightpanda
bash
curl -L -o lightpanda https://github.com/lightpanda-io/browser/releases/download/nightly/lightpanda-x86_64-linux
chmod a+x ./lightpanda

Docker

Docker

bash
undefined
bash
undefined

Supports amd64 and arm64

支持amd64和arm64

docker run -d --name lightpanda -p 9222:9222 lightpanda/browser:nightly
undefined
docker run -d --name lightpanda -p 9222:9222 lightpanda/browser:nightly
undefined

CLI Usage

CLI使用方法

Fetch a URL (dump rendered HTML)

获取URL(导出渲染后的HTML)

bash
./lightpanda fetch --obey_robots --log_format pretty --log_level info https://example.com
bash
./lightpanda fetch --obey_robots --log_format pretty --log_level info https://example.com

Start CDP Server

启动CDP服务器

bash
./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.
bash
./lightpanda serve --obey_robots --log_format pretty --log_level info --host 127.0.0.1 --port 9222
这会启动一个基于WebSocket的CDP服务器,用于程序化控制。

CLI Flags

CLI参数

FlagDescription
--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)
参数描述
--obey_robots
遵循robots.txt规则
--log_format pretty
生成人类可读的日志输出
--log_level info
日志详细程度:
debug
info
warn
error
--host 127.0.0.1
CDP服务器的绑定地址
--port 9222
CDP服务器的端口
--insecure_disable_tls_host_verification
禁用TLS验证(仅用于测试)

Playwright Integration

Playwright集成

Start the CDP server, then connect Playwright to it:
javascript
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();
启动CDP服务器后,将Playwright连接到它:
javascript
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

Puppeteer集成

javascript
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();
javascript
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

Go(chromedp)集成

go
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)
}
go
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

Python集成

python
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())
python
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

批量页面获取

javascript
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();
javascript
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

提取结构化数据

javascript
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,
  }));
});
javascript
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)

Docker Compose(与你的应用配合)

yaml
services:
  lightpanda:
    image: lightpanda/browser:nightly
    ports:
      - "9222:9222"
    restart: unless-stopped

  scraper:
    build: .
    depends_on:
      - lightpanda
    environment:
      - BROWSER_WS_ENDPOINT=ws://lightpanda:9222
yaml
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

支持的Web API

Lightpanda supports (partial, expanding):
  • DOM tree manipulation and querying
  • JavaScript execution (V8)
  • XMLHttpRequest (XHR)
  • Fetch API
  • Cookie management
  • Network interception
  • Proxy support
Lightpanda支持(部分支持,正在扩展):
  • DOM树操作与查询
  • JavaScript执行(V8)
  • XMLHttpRequest(XHR)
  • Fetch API
  • Cookie管理
  • 网络拦截
  • 代理支持

Configuration

配置

Environment VariableDescription
LIGHTPANDA_DISABLE_TELEMETRY
Set to
true
to opt out of usage metrics
环境变量描述
LIGHTPANDA_DISABLE_TELEMETRY
设置为
true
可选择退出使用数据统计

Performance Comparison

性能对比

MetricLightpandaChrome Headless
Memory~9x lessBaseline
Speed~11x fasterBaseline
Binary sizeSmall (Zig)Large (Chromium)
RenderingNo visual renderingFull rendering engine
指标LightpandaChrome无头模式
内存占用约少9倍基准值
速度约快11倍基准值
二进制文件大小小巧(基于Zig)庞大(基于Chromium)
渲染能力无视觉渲染完整渲染引擎

When to Use Lightpanda

何时使用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
适合使用Lightpanda的场景:
  • 运行需要浏览网页的AI Agent
  • 大规模批量抓取网页(内存/CPU节省至关重要)
  • 自动化表单提交与数据提取
  • 在资源有限的容器环境中运行
  • 需要CDP兼容性但无需完整视觉渲染
适合使用Chrome/Playwright的场景:
  • 需要像素级精确的截图或PDF生成
  • 需要完整的Web API支持(Lightpanda目前仅支持部分)
  • 视觉回归测试
  • 测试浏览器特定的渲染行为

Building from Source

从源码构建

Requires: Zig 0.15.2, Rust, CMake, system dependencies.
bash
undefined
依赖:Zig 0.15.2、Rust、CMake、系统依赖。
bash
undefined

Ubuntu/Debian dependencies

Ubuntu/Debian依赖

sudo apt install xz-utils ca-certificates pkg-config libglib2.0-dev clang make curl
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
git clone https://github.com/lightpanda-io/browser.git cd browser zig build

Optional: pre-build V8 snapshot for faster startup

可选:预构建V8快照以加快启动速度

zig build snapshot_creator -- src/snapshot.bin zig build -Dsnapshot_path=../../snapshot.bin
undefined
zig build snapshot_creator -- src/snapshot.bin zig build -Dsnapshot_path=../../snapshot.bin
undefined

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:
端口9222连接被拒绝:
  • 确保
    ./lightpanda serve
    正在运行
  • 如果从Docker/远程连接,检查是否设置了
    --host 0.0.0.0
Playwright脚本在更新后失效:
  • Lightpanda处于Beta阶段——不同版本间Playwright的能力检测可能表现不同
  • 固定Lightpanda版本或始终使用nightly版本
缺少Web API支持:

Links

链接