RepoPilotOpen in app →

go-rod/rod

A Chrome DevTools Protocol driver for web automation and scraping.

Healthy

Healthy across all four use cases

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 3mo ago
  • 16 active contributors
  • MIT licensed
Show all 6 evidence items →
  • CI configured
  • Tests present
  • Single-maintainer risk — top contributor 80% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/go-rod/rod)](https://repopilot.app/r/go-rod/rod)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/go-rod/rod on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: go-rod/rod

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/go-rod/rod shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 3mo ago
  • 16 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Single-maintainer risk — top contributor 80% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live go-rod/rod repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/go-rod/rod.

What it runs against: a local clone of go-rod/rod — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in go-rod/rod | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 109 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>go-rod/rod</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of go-rod/rod. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/go-rod/rod.git
#   cd rod
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of go-rod/rod and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "go-rod/rod(\\.git)?\\b" \\
  && ok "origin remote is go-rod/rod" \\
  || miss "origin remote is not go-rod/rod (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "browser.go" \\
  && ok "browser.go" \\
  || miss "missing critical file: browser.go"
test -f "page.go" \\
  && ok "page.go" \\
  || miss "missing critical file: page.go"
test -f "element.go" \\
  && ok "element.go" \\
  || miss "missing critical file: element.go"
test -f "lib/cdp/client.go" \\
  && ok "lib/cdp/client.go" \\
  || miss "missing critical file: lib/cdp/client.go"
test -f "hijack.go" \\
  && ok "hijack.go" \\
  || miss "missing critical file: hijack.go"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 109 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~79d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/go-rod/rod"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Rod is a high-level Chrome DevTools Protocol (CDP) driver for Go that enables programmatic control of headless Chrome/Chromium browsers for web automation and scraping. It abstracts away CDP complexity while exposing low-level packages for advanced customization, and includes features like auto-wait for elements, request hijacking, download handling, and iframe/shadow DOM support. Monolithic main package (browser.go, element.go, context.go at root) with low-level helpers in lib/launcher (browser discovery/download), lib/examples (usage patterns), and fixtures/ (test HTML/JS assets). State is managed through context-chained operations; DevTools Protocol marshaling uses ysmood/gson for JSON. Test coverage uses *_test.go files alongside examples_test.go.

👥Who it's for

Go developers building web automation tools, bot frameworks, and scraping applications who need a production-grade CDP client with intuitive APIs and thread-safe operations, particularly those wanting to avoid DevTools Protocol boilerplate.

🌱Maturity & risk

Rod is production-ready and actively maintained. The codebase enforces 100% test coverage via CI, has comprehensive examples in examples_test.go and lib/examples/, and demonstrates mature practices (linting via .golangci.yml, multiple test workflows for Linux/other platforms, PR/issue templates). The primary maintainer is ysmood, with strong integration with complementary ysmood libraries (goob, leakless, gotrace) suggesting healthy ecosystem development.

Standard open source risks apply.

Active areas of work

No recent commit timestamps visible in the provided snapshot, but the repo maintains active CI workflows (check-examples.yml, test-linux.yml, docker.yml). The code appears stable rather than in active feature development; focus is likely on CDP protocol compliance, edge-case handling (nested iframes, shadow DOMs), and ecosystem maturity. Discord room and GitHub discussions suggest ongoing user support.

🚀Get running

git clone https://github.com/go-rod/rod.git
cd rod
go mod download
go test ./... # Run full test suite (100% coverage enforced)

Daily commands: No traditional 'dev server'—Rod is a library. Run examples with go test -run Example, or individual test suites with go test ./... -v. For local testing: go test -race for concurrency checks (thread-safe guarantees). Docker available via docker.yml workflow.

🗺️Map of the codebase

  • browser.go — Entry point for the Rod library; defines the Browser type and lifecycle management that all automation flows depend on.
  • page.go — Core Page abstraction wrapping DevTools Protocol pages; essential for navigation, evaluation, and element interactions.
  • element.go — Element selector and interaction API; critical for locating and manipulating DOM nodes during automation.
  • lib/cdp/client.go — Low-level WebSocket client for Chrome DevTools Protocol communication; foundation of all browser control.
  • hijack.go — Request/response interception system enabling network manipulation, a key advanced automation feature.
  • lib/launcher/launcher.go — Browser process management and automatic download logic; required for starting controlled Chrome instances.
  • context.go — Context-based timeout and cancellation patterns woven throughout the API; essential for understanding async control flow.

🛠️How to make changes

Add a new high-level automation helper method

  1. Define the method receiver on Page or Element in page.go or element.go with chainable context pattern (page.go)
  2. Use existing CDP protocol calls (e.g., EvaluateExpression, CallbackResult) to implement the behavior (lib/cdp/client.go)
  3. Add context timeout handling following the pattern in context.go using WithTimeout (context.go)
  4. Write table-driven tests in page_test.go or element_test.go with fixture HTML files (fixtures/)

Customize browser launch behavior

  1. Review default launch flags in lib/defaults/defaults.go to understand baseline configuration (lib/defaults/defaults.go)
  2. Call rod.New() and modify the Launcher before browser.Connect() to add custom arguments or paths (browser.go)
  3. Reference lib/launcher/launcher.go for Flags struct and launch option building logic (lib/launcher/launcher.go)

Intercept and modify network traffic

  1. Call page.HijackRequests() to enable request interception following the hijack.go patterns (hijack.go)
  2. Attach handlers that receive *http.Request and return modified responses or allow passthrough (hijack.go)
  3. Use page.MustWaitRequestIdle() to wait for all hijacked requests to complete (page.go)
  4. Write tests using fixtures/resource.html or fixtures/fetch.html to verify interception behavior (fixtures/)

Add support for a new DevTools Protocol feature

  1. Review Chrome DevTools Protocol spec and add new message types to lib/cdp (or extend existing structs) (lib/cdp/client.go)
  2. Implement a new method on *Browser or *Page that calls Call() with the new protocol domain/method (browser.go)
  3. Wrap with context timeout and error handling following patterns in context.go and error.go (context.go)
  4. Add integration tests to browser_test.go or page_test.go with appropriate fixtures (browser_test.go)

🔧Why these technologies

  • Chrome DevTools Protocol (CDP) — Direct, low-latency control of Chrome/Chromium via WebSocket without browser extension overhead; enables headless automation and inspection.
  • Go (language choice) — Statically typed, compiled, concurrent (goroutines); excellent for long-running automation tasks and simple deployment without runtimes.
  • Context-based timeouts — Idiomatic Go pattern for cancellation and deadline propagation; prevents zombie goroutines and hanging automation jobs.
  • Embedded JavaScript assets — Avoids external file dependencies; simplifies distribution; enables runtime stability monitoring and DOM querying without npm/bundlers.

⚖️Trade-offs already made

  • High-level API wrapping low-level CDP calls

    • Why: Reduces boilerplate and cognitive load for common use cases (click, type, wait) while still exposing low-level CDP via Call() for advanced users.
    • Consequence: Code size increases; multiple ways to accomplish same goal can confuse newcomers; maintenance burden of keeping both levels in sync.
  • Automatic browser download and installation

    • Why: Lowers barrier to entry; users don't need to manage Chrome binaries separately.
    • Consequence: First run is slower; disk footprint grows; may conflict with system Chrome versions; adds complexity to lib/launcher.
  • Request hijacking via Network domain enable/disable per page

    • Why: Enables powerful network mocking without full proxy setup; fits DevTools Protocol architecture.
    • Consequence: Hijacking is per-page, not global; some proxy patterns difficult to express; performance overhead from JS event marshalling.
  • Thread-safe API (all operations synchronized)

    • Why: Simplifies concurrent automation in Go; eliminates races when multiple goroutines control same browser/page.
    • Consequence: Lock contention on shared Browser handle; less parallelism within single Browser instance; slight latency overhead per RPC.

🚫Non-goals (don't propose these)

  • Not a test framework (no assertions, reporting, or test runner integration—see examples_test.go for usage patterns).
  • Not a Node.js/Playwright replacement (Go-only; does not expose JS-first puppeteer-style patterns).
  • Not a proxy or HTTP client (focuses on browser automation, not general-purpose network manipulation).
  • Does not provide GUI or visual regression testing (raw screenshots/PDFs only; no visual diff tools included).
  • Does not support non-Chromium browsers (Chrome/Chromium only; Safari, Firefox not supported).

🪤Traps & gotchas

Browser download: lib/launcher auto-downloads Chrome if not found; set BROWSER_SKIP_DOWNLOAD=true to use system Chrome and avoid network I/O in offline environments. Port conflicts: headless browser uses dynamic ports by default but may conflict in CI; use browser.MustGetWSURL() for explicit discovery. Context cancellation: chained contexts (ctx.Timeout) don't auto-cleanup resources; always defer browser.MustClose() even if context cancels. Iframe navigation: nested iframes require page.Frames() traversal; easy to accidentally wait on parent when target is child frame. Socket not available: on macOS/Linux, ensure no prior zombie Chrome processes (ysmood/leakless mitigates, but check lsof -i if stale connections observed).

🏗️Architecture

💡Concepts to learn

  • Chrome DevTools Protocol (CDP) — Rod is fundamentally a CDP client; understanding protocol primitives (domains, commands, events) explains why API surfaces look like method calls and why certain operations require two-step event waiting
  • Two-Step Event Handling (via ysmood/goob) — Rod's event model prevents race conditions where events fire before listeners attach; critical to understanding WaitEvent() pattern and why you should never skip event subscriptions
  • Context-Based Chaining & Timeout Propagation — Rod uses Go context.Context for intuitive timeout/cancellation without explicit error returns; enables natural ctx.Timeout(5*time.Second) patterns for long-running browser operations
  • Shadow DOM & Iframe Traversal — Rod automatically handles nested iframes and shadow DOMs (mentioned as 'correctly handles' in features); understanding frame isolation is essential when targeting elements in cross-origin or encapsulated contexts
  • Zombie Process Prevention (ysmood/leakless) — Rod avoids leaving stray Chrome processes after crashes via leakless integration; critical for production reliability in containers/CI where process cleanup is enforced
  • Request Hijacking & Network Mocking — Rod's HijackRequests() feature allows intercepting and modifying network traffic without proxy setup; essential for testing offline scenarios, simulating failures, and load testing
  • Thread-Safe CDP Operations — Rod advertises all operations as thread-safe; understanding how concurrent goroutines share a single DevTools Protocol connection prevents common race conditions in multi-threaded scraping
  • chromedp/chromedp — Direct competitor in Go CDP space; Rod's README explicitly benchmarks against it (lib/examples/compare-chromedp), both targeting same problem domain with different API philosophies
  • go-echarts/go-echarts — Complementary tool for chart rendering in headless mode; common user pattern chains Rod with go-echarts for automated data visualization
  • ysmood/leakless — Critical dependency for Rod's zombie process prevention; governs browser lifecycle reliability in long-running applications
  • ysmood/goob — Foundational event handling library (two-step WaitEvent) that prevents race conditions in Rod's async protocol handling
  • go-rod/go-rod-chinese — Chinese-language API documentation mirror; community translation resource for non-English speakers adopting Rod

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive error handling tests in error_test.go

The repo has error.go but no corresponding error_test.go file. Given that Rod is a DevTools Protocol driver that handles complex async operations, error scenarios (timeouts, context cancellation, protocol errors, connection failures) are critical. Testing error handling patterns would improve reliability and serve as documentation for users on how errors propagate through the chained context design.

  • [ ] Create error_test.go with tests for error type assertions and error wrapping
  • [ ] Add tests for context cancellation error handling across browser, page, and element operations
  • [ ] Test DevTools protocol error responses and how they're transformed into Go errors
  • [ ] Add tests verifying timeout errors work correctly with the chained context design
  • [ ] Document error handling patterns in test comments for user reference

Add context.go integration tests to verify context cancellation propagation

The repo has context.go but no context_test.go file. Since Rod's core design philosophy emphasizes 'Chained context design, intuitive to timeout or cancel long-running tasks', this feature needs comprehensive test coverage. Currently, context behavior is likely tested only incidentally through other tests, making it hard to verify context propagation works correctly across nested operations.

  • [ ] Create context_test.go with tests for context timeout propagation
  • [ ] Add tests verifying that cancelling parent context cancels all child operations
  • [ ] Test deadline behavior when multiple contexts with different deadlines are nested
  • [ ] Add tests for context cleanup and resource release on cancellation
  • [ ] Test integration with Browser, Page, and Element to ensure context flows through the entire chain

Add missing CI workflow for security scanning and dependency auditing

The repo has workflows for testing and examples checking (.github/workflows/), but no automated security scanning or Go dependency vulnerability checking. With 6 external dependencies and a tool that controls browsers (high privilege), adding security scanning would catch supply chain vulnerabilities early and instill confidence in users relying on Rod for production web automation.

  • [ ] Create .github/workflows/security.yml with go-sec or gosec for Go security scanning
  • [ ] Add step to run 'go mod verify' to detect dependency tampering
  • [ ] Integrate GitHub's native Dependabot or add Nancy for Go dependency vulnerability scanning
  • [ ] Configure the workflow to fail on high-severity vulnerabilities
  • [ ] Add SECURITY.md in .github/ documenting the vulnerability reporting process

🌿Good first issues

  • Add comprehensive error examples to examples_test.go for common DevTools Protocol failures (e.g., element not found, timeout, navigation failure); currently examples focus on happy paths but error handling is under-documented.
  • Expand fixtures/ coverage for accessibility testing (add fixtures/a11y-landmarks.html, fixtures/aria-labels.html with corresponding test cases); element.go supports accessibility queries but no test fixtures demonstrate them.
  • Create lib/examples/visual-regression/ folder with a runnable example showing screenshot comparison for regression testing; README mentions high-level helpers but no built-in visual testing example exists despite being a common use case.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 1cd7eb9 — doc (ysmood)
  • 80e536d — add sponsors to readme (ysmood)
  • 420383d — use pixelmator pro for the logo file (ysmood)
  • 393ac0d — feat: map session cookie expires to zero time value #1159 (#1160) (kvii)
  • 686e0ad — feat: add wrap for window-size and window-position flag (#1158) (kvii)
  • 3025dde — SetHeader should replace entries with the same key (#1134) (lihe07)
  • 73907a8 — add support for google chrome on nixos (#1136) (sacsbrainz)
  • 10bc116 — docs: update README.md (#1146) (eltociear)
  • 0096e53 — opt: formatToJSFunc use string plus (#1101) (somnus-L)
  • 945ca02 — fix flaky test (ysmood)

🔒Security observations

The Rod project demonstrates a reasonable security posture as a web automation framework. The codebase uses Go's built-in module system with locked dependencies via go.mod/go.sum. Primary concerns are: (1) potential XSS risks inherent to a framework that executes JavaScript in web contexts - this requires careful API design and user education; (2) dependency management and monitoring for transitive vulnerabilities; (3) missing security policy and automated security scanning in CI/CD. The project would benefit from a SECURITY.md file, addition of SAST tools to the pipeline, and security-focused documentation for developers using this framework. No hardcoded credentials or obvious injection vulnerabilities were detected in the file structure provided.

  • Medium · Potential XSS Risk in Web Automation Framework — element.go, browser.go, input.go (general architecture). Rod is a Chrome DevTools Protocol driver designed for web automation and scraping. The framework executes JavaScript in web pages and interacts with page content. If user-controlled input is not properly sanitized before being injected into page evaluation contexts, XSS vulnerabilities could occur. The presence of fixtures with HTML files and JavaScript execution capabilities increases the attack surface. Fix: Implement strict input validation and sanitization for all user-supplied data before passing to page evaluation methods. Use parameterized evaluation contexts where possible. Provide security guidance in documentation about safe usage patterns.
  • Medium · Dependency on External Packages Without Lock File Verification — go.mod, go.sum. The project depends on multiple packages from github.com/ysmood/* (fetchup, goob, got, gotrace, gson, leakless, gop). While go.mod and go.sum are present for version pinning, there's a risk if these dependencies introduce vulnerabilities. The indirect dependency 'gop' is included without direct visibility into its usage. Fix: Regularly run 'go list -u -m all' and 'go mod why' to audit dependencies. Implement automated dependency scanning using tools like Dependabot or Snyk. Review transitive dependencies (especially 'gop') for security issues. Consider using 'go mod tidy' and keeping dependencies up-to-date.
  • Low · Fixture Files May Contain Test Payloads — fixtures/ directory (e.g., fixtures/alert.html, fixtures/shadow-dom.html). The fixtures directory contains HTML, JavaScript, and other test assets. While these are intended for testing, maliciously crafted fixtures could be used to test security features. If fixture files are ever deployed or exposed, they could contain XSS or other payloads. Fix: Ensure fixture files are clearly marked as test-only and never included in production builds. Add documentation warning developers about the nature of fixture content. Consider using .gitignore or build exclusions to prevent accidental deployment.
  • Low · Missing Security Policy Documentation — .github/ directory. No SECURITY.md file is present in the repository root. This makes it difficult for security researchers to responsibly report vulnerabilities. The existence of CODE_OF_CONDUCT.md and CONTRIBUTING.md is good, but security reporting procedures are not explicitly documented. Fix: Create a SECURITY.md file following the GitHub standard for security vulnerability reporting. Include instructions for responsible disclosure and expected response times. Reference trusted contact points for security issues.
  • Low · No Apparent Security Scanning in CI/CD Pipeline — .github/workflows/. While GitHub workflows exist (test-linux.yml, test-other-platforms.yml, check-examples.yml), there's no visible SAST (Static Application Security Testing) or dependency scanning workflow configuration in the provided file structure. Fix: Add security scanning workflows such as: GitHub CodeQL analysis, Go security scanner (gosec), OWASP Dependency-Check, or similar SAST tools. Integrate these into the CI/CD pipeline to automatically detect vulnerabilities on each commit.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · go-rod/rod — RepoPilot