Lightpanda
Lightpanda architecture: connection-scoped browser state and protocol domains
Trace browser, session, page and target lifetimes, then separate optional observations from full web-platform compatibility.
What you will learn
- Track Browser, Session and target ownership explicitly.
- One connection does not offer unrestricted simultaneous contexts.
- Observation format and loading policy are independent.
Before you start
- Basic HTTP, JSON and browser lifecycle knowledge
- An owned fixture with explicit expected output
Explain the chapter’s implementation boundary and verify its proposed task or independent byte-model example.
Key takeaways
- Track Browser, Session and target ownership explicitly.
- One connection does not offer unrestricted simultaneous contexts.
- Observation format and loading policy are independent.
Follow ownership rather than familiar API names
Browser.zig owns a JavaScript environment, an HTTP client, an optional session and page-related allocation pools. Its comments describe one session per Browser instance. It also keeps permissions, selector cache, viewport overrides and a lazily created screenshot renderer. These owners help explain what survives navigation and what must be released during teardown.
The frame-ID generator belongs to Browser rather than Session so fresh contexts on one CDP connection do not immediately reuse target identifiers. Its increment uses wrapping arithmetic. The scope choice addresses lifecycle uniqueness across sessions; it is not a cryptographic identity or an authorization token.
The Target domain enforces concrete limits
createBrowserContext catches an existing context and returns an error instead of creating another simultaneous context on that connection. createTarget similarly rejects when a target is already loaded. getBrowserContexts returns the current context or an empty list. Those branches matter more to a client pool design than the fact that the method names resemble Chrome’s protocol.
Some context options generate not-implemented warnings, while a proxy setting changes the browser HTTP client. Do not interpret a successful response as evidence that every supplied option took effect. Test the options your isolation and cleanup design actually relies on, and keep connection ownership explicit in concurrent workloads.
Observation and resource loading are separate controls
The LP domain implements Markdown and semantic-tree responses, with options such as pruning, interactive-only output and maximum depth for the latter. Resource loading is configured separately for images, frames, workers and external stylesheets. Changing the observation format does not by itself prove that all resources needed for the task were loaded.
The base LoadResources structure defaults those four resource flags to false, while mode-specific code can alter behavior. Report the effective mode and settings in experiments instead of applying one default to every invocation. The architecture diagram is an editorial ownership map, not a measured thread topology or a claim of complete browser isolation.
Implementation steps
- 1
Draw ownership for one CDP connection.
- 2
Test context creation and disposal before adding concurrency.
- 3
Record effective resource loading and observation options.
Copy-ready example
CDP connection
Browser: JS environment + HTTP client + frame IDs
current session / context
current page target
LP observations and resource loading are separate settings.Frequently asked questions
Can one connection create unlimited simultaneous contexts?
No. The inspected Target handler explicitly rejects a second active browser context.
Does Markdown output imply full resource loading?
No. The output representation and resource policy are separate; verify effective settings for the selected mode.
Sources
- README.mdSource checked 2026-09-08
- LICENSESource checked 2026-09-08
- DockerfileSource checked 2026-09-08
- build.zig.zonSource checked 2026-09-08
- src/Config.zigSource checked 2026-09-08
- src/browser/Browser.zigSource checked 2026-09-08
- src/server/cdp/domains/target.zigSource checked 2026-09-08
- src/server/cdp/domains/page.zigSource checked 2026-09-08
- src/server/cdp/domains/lp.zigSource checked 2026-09-08
- src/server/cdp/SafeString.zigSource checked 2026-09-08
- src/network/RobotsGate.zigSource checked 2026-09-08
- src/telemetry/telemetry.zigSource checked 2026-09-08