Modern browser automation for Zig with a CDP/BiDi-first API, deterministic discovery, and production gates.
- CDP/BiDi-first modern API (
driver.modern.*) with typed domain clients. - Auto-launch and auto-attach flows that wait for real protocol readiness.
- Common utility paths are centralized (
driver.path,driver.strings,driver.json,driver.io) to keep behavior consistent across modules. - Deterministic browser discovery (PATH + known paths + OS probes + managed cache).
- Typed waits, cancellation tokens, lifecycle events, timeout policies, diagnostics.
- Typed cookie query/export helpers and built-in session cache.
- Runtime Lightpanda download/install support (no build-time dependency).
- Production tooling: adversarial detection gate, matrix, release bundle.
const std = @import("std");
const driver = @import("alldriver");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var session = try driver.modern.launchAuto(allocator, .{
.kinds = &.{ .chrome, .firefox, .lightpanda },
.allow_managed_download = false,
.profile_mode = .ephemeral,
.headless = true,
});
defer session.deinit();
var page = session.page();
try page.navigate("https://example.com");
_ = try session.waitFor(.{ .dom_ready = {} }, .{ .timeout_ms = 30_000 });
}zig fetch --save git+https://github.com/SmallThingz/alldriverThen add the dependency import in your build.zig as usual.
driver.modern.discover(...)driver.modern.launch(...)driver.modern.launchAuto(...)driver.modern.attach(...)
session.page()session.runtime()session.network()session.input()session.log()session.storage()session.contexts()session.targets()
session.waitFor(target, opts)session.waitForCookie(query, opts)session.waitForAsync(target, opts)session.waitForCookieAsync(query, opts)driver.CancelTokensession.onEvent(filter, callback)/session.offEvent(id)session.addInitScript(script)/session.removeInitScript(id)(pre-document init scripts)- Lifecycle hook kinds:
- Navigation/reload:
navigation_started,navigation_completed,navigation_failed,reload_started,reload_completed,reload_failed - Deterministic milestones:
response_received,dom_ready,scripts_settled - Wait lifecycle:
wait_started,wait_satisfied,wait_timeout,wait_canceled,wait_failed - Action lifecycle:
action_started,action_completed,action_failed - Network observation:
network_request_observed,network_response_observed - Challenge/cookie:
challenge_detected,challenge_solved,cookie_updated
- Navigation/reload:
- Key semantics:
navigation_startedis emitted before each navigate attempt, including attempts that later fail.navigation_completedis emitted only after successful navigate; failures emitnavigation_failed.- Wait APIs emit the
wait_*lifecycle hooks, including failure/cancel/timeout outcomes. - Session actions (
click,typeText,evaluate) emitaction_*hooks around each attempt. - Network telemetry keeps request/response metadata, redirect chains, and per-request status timelines.
network.records(allocator, include_bodies=true)attempts full response-body capture via protocol APIs where available.network.frames(...)andnetwork.serviceWorkers(...)provide frame/service-worker introspection from protocol notifications.- Snapshot bundles are captured per navigation phase and retrievable via
network.navigationSnapshots(...). challenge_detected(challenge heuristic became active during wait polling)challenge_solved(challenge heuristic transitioned back to clear)cookie_updatedis emitted after successfulsetCookiewithchangeandsourcemetadata.reload()emits both reload hooks and navigation hooks withcause=.reloadfor symmetry.
- Filter semantics:
filter.kinds = &.{}subscribes to all hook kinds.filter.domainis case-insensitive and matches exact host or subdomain suffix.- Domain extraction uses URL host for navigation/reload/network/challenge hooks and
cookie.domainforcookie_updated. - Domain filtering does not apply to hook kinds without URL/domain payloads (
wait_*,action_*).
session.setTimeoutPolicy(...)session.timeoutPolicy()session.lastDiagnostic()driver.modern.setHardErrorLogger(...)
driver.extension_hooks.registerHooks(...)- Hook kinds:
score_install(adjust discovery scoring)launch_args(rewrite/append process args before spawn)session_init(notified after session protocol readiness)event_observer(extension event sink for explicitnotifyEventcalls)
session.storage().queryCookies(...)session.storage().buildCookieHeaderForUrl(...)driver.SessionCacheStore.open/load/save/saveWithOptions/invalidate/cleanupExpired
- Chromium-family browsers via CDP.
- Firefox/Gecko via BiDi.
- CDP-capable webviews:
webview2,electron,android_webview.
- Targets without usable CDP/BiDi surfaces on the host are discovered/classified but not driven.
When managed_cache_dir is unset, default paths are:
- Linux:
$XDG_CACHE_HOME/alldriver/browsers(fallback$HOME/.cache/alldriver/browsers) - macOS:
$HOME/Library/Caches/alldriver/browsers - Windows:
%LOCALAPPDATA%\\alldriver\\browsers
discover() always scans managed cache.
allow_managed_download controls whether provisioning/download is allowed.
Programmatic:
const installed = try driver.modern.downloadLightpandaLatest(allocator, .{
.cache_dir = null,
.tag = null,
.expected_sha256_hex = null,
});
defer allocator.free(installed);Tooling:
zig build tools -- download-lightpanda# core
zig build test
zig build examples
zig build run
# tool sanity
zig build tools -- self-test
# adversarial gate
zig build tools -- adversarial-detection-gate --allow-missing-browser=1
# production gate
zig build production-gate
zig build tools -- production-gate --strict-ga- Browser binaries for your chosen targets (Chrome/Edge/Firefox/Brave/etc.).
- Optional Lightpanda binary (auto-downloaded at runtime if requested).
- Optional webview runtimes/tools when using those flows (
msedgewebview2,electron, Android bridge tools such asadborshizuku/rish).
If you only use discover/launch/attach against installed desktop browsers, no additional tooling binaries are required by the library core.
git,bash,tar,date,which/where,chmodgpg(sign/verify)ssh,scp,rsync(remote matrix)qemu-system-x86_64,qemu-img,curl,ssh-keygen(VM workflows)
alldriver is for standards-compliant automation (QA/testing/scripting).
It does not provide built-in detection-bypass/evasion primitives.
/home/a/projects/zig/browser_driver/DOCUMENTATION.md/home/a/projects/zig/browser_driver/examples/README.md/home/a/projects/zig/browser_driver/CONTRIBUTING.md/home/a/projects/zig/browser_driver/SECURITY.md