Showcase · Headless browser

NeoBrowser

A headless web browser for agents and crawlers, in the spirit of Lightpanda.

No rendering, just the page's content and its controls. DNS, TLS 1.3 and 1.2 with certificate verification, HTTP/1.1, cookies, the WHATWG HTML parser, CSS selectors and form submission are all written in the language and ship as one static binary, with no OpenSSL, libcurl or C library underneath.

9.2×faster than Lightpanda at loading python.org's home page and reading it from the DOM; 24.7× headless Chrome, with a third of Lightpanda's memory

Results

Page load python.org home page, 50 KB: fresh process to exit ms, lower is better
NeoBrowser 6.9 ms
Lightpanda 63.5 ms
Chrome 170 ms

9.20× faster than Lightpanda24.7× faster than Chrome

Page load Wikipedia article “Web browser”, 341 KB ms, lower is better
NeoBrowser 23.3 ms
Lightpanda 137 ms
Chrome 261 ms

5.87× faster than Lightpanda11.2× faster than Chrome

Page load WHATWG HTML parsing chapter, 825 KB ms, lower is better
NeoBrowser 57.8 ms
Lightpanda 261 ms
Chrome 441 ms

4.51× faster than Lightpanda7.63× faster than Chrome

Page load Hacker News front page, 35 KB ms, lower is better
NeoBrowser 4.8 ms
Lightpanda 57.9 ms
Chrome 181 ms

12.1× faster than Lightpanda37.8× faster than Chrome

Page load example.com, 340 bytes: mostly process start ms, lower is better
NeoBrowser 1.7 ms
Lightpanda 44.3 ms
Chrome 145 ms

26.1× faster than Lightpanda85.3× faster than Chrome

Peak memory python.org home page MiB, lower is better
NeoBrowser 7.00 MiB
Lightpanda 21.4 MiB
Chrome 97.7 MiB

3.06× less than Lightpanda14.0× less than Chrome

Peak memory Wikipedia article, 341 KB MiB, lower is better
NeoBrowser 10.0 MiB
Lightpanda 21.7 MiB
Chrome 100.2 MiB

2.17× less than Lightpanda10.0× less than Chrome

Peak memory WHATWG HTML parsing chapter, 825 KB MiB, lower is better
NeoBrowser 16.9 MiB
Lightpanda 26.7 MiB
Chrome 106.9 MiB

1.58× less than Lightpanda6.33× less than Chrome

Deployed size What the browser needs besides the operating system MiB, lower is better
NeoBrowser 13.4 MiB
Lightpanda 73.6 MiB
Chrome 274.1 MiB

5.48× less than Lightpanda20.4× less than Chrome

x86-64 Linux, every browser on the same two AMD EPYC Genoa vCPUs · Vultr dedicated 2 vCPU instance, Ubuntu 24.04, Linux 6.8 · 1 November 2026 · bench/compare.py

Medians of 20 runs after a warm-up. Every run is a fresh process from start to exit, timed together with its peak RSS by GNU time, and every page comes from a local server so the network is out of the picture. The pages are saved copies of the real ones with scripts, styles and external subresources removed, because NeoBrowser does not run JavaScript or CSS yet; Lightpanda and Chrome still start their JavaScript engines. All three build the page's DOM: NeoBrowser then prints the readable text, Lightpanda (fetch --dump) and Chrome (--dump-dom) serialize the tree. Lightpanda 1.1.0-nightly.11471; Chrome for Testing 156.0.8078.80, headless shell. Chrome's memory is its largest process, which understates its total. Deployed size: NeoBrowser's static binary, with no C library; the Lightpanda binary, which also loads the system C library; the headless shell's directory. Not implemented yet: JavaScript, CSS layout, HTTP/2 and the CDP protocol, so Puppeteer and Playwright cannot drive it yet.

What it does

  • Sessions an agent drives with JSON commands: go to a page, click links and buttons, fill and submit forms, check boxes, go back
  • The WHATWG HTML parser: 99.4% of the html5lib tree-construction tests and all of the tokenizer tests that start in the data state
  • CSS selectors with querySelector and matches, checked against soupsieve: combinators, attributes, :not/:is, :nth-child of S and form states
  • Cookies across redirects, and GET or POST forms in urlencoded, multipart or plain text
  • TLS 1.3 and 1.2 with certificate chains verified against the system trust store: RSA and ECDSA (P-256, P-384)
  • HTTP/1.1 with chunked bodies, gzip and deflate, and redirects that change method as the standard says

Usage

terminal
$ neobrowser fetch https://www.python.org/ --dump title
Welcome to Python.org

# readable text, links (URL, tab, text) or the raw HTML
$ neobrowser fetch https://news.ycombinator.com/ --dump links
session.jsonl
{"cmd":"goto","url":"https://example.org/login"}
{"cmd":"fill","selector":"input[name=user]","value":"ada"}
{"cmd":"check","selector":"#remember"}
{"cmd":"click","text":"Sign in"}
{"cmd":"text"}
terminal
# one JSON reply per command, such as
# {"ok":true,"url":"…","status":200,"title":"…"}
$ neobrowser session < session.jsonl