hardkoded/puppeteer-sharp
Headless Chrome .NET API
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit today
- ✓5 active contributors
- ✓MIT licensed
Show 3 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Single-maintainer risk — top contributor 93% 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.
[](https://repopilot.app/r/hardkoded/puppeteer-sharp)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/hardkoded/puppeteer-sharp on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: hardkoded/puppeteer-sharp
Generated by RepoPilot · 2026-05-10 · 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:
- 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. - 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.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/hardkoded/puppeteer-sharp 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 today
- 5 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Single-maintainer risk — top contributor 93% 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 hardkoded/puppeteer-sharp
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/hardkoded/puppeteer-sharp.
What it runs against: a local clone of hardkoded/puppeteer-sharp — 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 hardkoded/puppeteer-sharp | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of hardkoded/puppeteer-sharp. If you don't
# have one yet, run these first:
#
# git clone https://github.com/hardkoded/puppeteer-sharp.git
# cd puppeteer-sharp
#
# 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 hardkoded/puppeteer-sharp and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "hardkoded/puppeteer-sharp(\\.git)?\\b" \\
&& ok "origin remote is hardkoded/puppeteer-sharp" \\
|| miss "origin remote is not hardkoded/puppeteer-sharp (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 master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~0d)"
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/hardkoded/puppeteer-sharp"
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).
⚡TL;DR
Puppeteer Sharp is a .NET port of the Node.js Puppeteer API that provides headless Chrome/Firefox automation for web scraping, testing, and PDF generation. It allows .NET developers to programmatically control Chromium-based browsers via the Chrome DevTools Protocol (CDP) and WebDriver BiDi, with recent support for AOT compilation and cross-browser Firefox testing. Standard .NET solution structure: core library in src/ (main C# implementation), companion packages PuppeteerSharp.Cdp (Chrome-only, minimal binary footprint) and PuppeteerSharp.AspNetFramework, runnable demos in demos/ (PuppeteerSharpPdfDemo, etc.), documentation in docfx_project/, and CI workflows in .github/workflows/. Skills-driven automation tasks in .claude/skills/ for common operations.
👥Who it's for
.NET developers (C# on .NET Framework 4.6.1+, .NET Core 2.0+, and .NET 8) who need to automate browser workflows like end-to-end testing, screenshot capture, PDF generation, and web scraping without spinning up separate Node.js processes.
🌱Maturity & risk
Production-ready and actively maintained. The project has extensive CI/CD pipelines (.github/workflows/dotnet.yml, leak-check.yml, PushNugetPackageToNugetOrg.yml), published NuGet packages with recent v21.0.0 release featuring WebDriver BiDi support, and comprehensive API documentation via DocFX. The codebase is substantial (3.4M lines of C#) with established patterns and contributions guidelines.
Low-to-moderate risk. It's a single-maintainer project (hardkoded) dependent on tracking upstream Puppeteer changes, which can introduce breaking changes during major version syncs. The CDP/BiDi protocols are actively evolving, requiring constant updates. No visible dependency bloat issues, but the project requires Chrome/Firefox binaries at runtime, adding deployment complexity.
Active areas of work
Active development on WebDriver BiDi support (v21.0.0 release notes mention Firefox testing), AOT compilation hardening (v19.0.0 added AOT support documented in docfx_project/docs/AOT.md), and upstream Puppeteer change synchronization. The .claude/skills/ directory indicates structured work on release management and upstream integration.
🚀Get running
git clone https://github.com/hardkoded/puppeteer-sharp.git
cd puppeteer-sharp
dotnet build
dotnet test
For demos: dotnet run --project demos/PuppeteerSharpPdfDemo/PuppeteerSharpPdfDemo.csproj
Daily commands:
Build: dotnet build. Run tests: dotnet test. Run a specific demo: dotnet run --project demos/PuppeteerSharpPdfDemo/PuppeteerSharpPdfDemo.csproj. Workflows in .github/workflows/dotnet.yml show the canonical build/test pipeline.
🗺️Map of the codebase
- src/PuppeteerSharp: Main library implementation; contains Browser, Page, Frame, ElementHandle, Locator classes and CDP protocol handling
- docfx_project/docfx.json: DocFX configuration that generates the published API docs at puppeteersharp.com; defines site structure and metadata
- .github/workflows/dotnet.yml: Primary CI/CD pipeline: runs build, tests, and leak checks on every push; defines the canonical test command
- CONTRIBUTING.md: Contribution guidelines including code standards, PR review expectations, and issue triage process
- Directory.Build.props: Centralized MSBuild configuration for all C# projects; controls version, target frameworks, and shared properties
- .claude/skills/implement-upstream-change/SKILL.md: Documents the process for syncing breaking changes from upstream Node.js Puppeteer releases
🛠️How to make changes
Core API additions go in src/ (mirror the Puppeteer Node.js API signatures). Implement BiDi features: see .claude/skills/implement-bidi-feature/SKILL.md for structured approach. Add docs to docfx_project/docs/ (Markdown format). Test additions in the corresponding test project. Follow CONTRIBUTING.md for PR process.
🪤Traps & gotchas
Chrome/Firefox binaries are downloaded at runtime and cached; first run is slow and requires network access. CDP message marshaling is case-sensitive and version-dependent; breaking changes in Chromium DevTools Protocol may require library updates before new browser versions work. ASP.NET Classic support requires the separate PuppeteerSharp.AspNetFramework package due to runtime differences. AOT compilation (enabled in v19+) restricts reflection-based APIs; see docfx_project/docs/AOT.md for constraints. WebDriver BiDi support is newer; prefer CDP for mature scenarios.
💡Concepts to learn
- Chrome DevTools Protocol (CDP) — The low-level JSON-RPC protocol that Puppeteer Sharp uses to communicate with Chromium; understanding CDP messages is essential for debugging protocol issues and implementing new features
- WebDriver BiDi — The emerging standardized browser protocol replacing CDP; v21.0.0 added support, making Puppeteer Sharp compatible with Firefox and future cross-browser scenarios
- Ahead-of-Time (AOT) Compilation — Puppeteer Sharp v19+ supports .NET AOT, allowing compilation to native binaries without JIT; critical for binary size reduction and deployment constraints, though reflection is restricted
- Async/Await Pattern in .NET — The entire Puppeteer Sharp API uses async methods (LaunchAsync, GotoAsync, EvaluateAsync); essential for handling long-running browser operations without blocking threads
- Process Lifecycle Management — Puppeteer Sharp manages browser process spawning, stdin/stdout capture via pipes, and graceful termination; understanding process pooling and cleanup is critical for production stability
- JSON-RPC 2.0 Message Framing — CDP and BiDi communicate via JSON-RPC over WebSocket; Puppeteer Sharp must correctly parse/send request IDs, handle batching, and correlate responses to pending tasks
- Document Object Model (DOM) Traversal & Selectors — The Locators API (docfx_project/docs/Locators.md) wraps DOM queries sent to the browser; understanding CSS/XPath selectors and frame context switching is vital for element interaction
🔗Related repos
puppeteer/puppeteer— The upstream Node.js Puppeteer project that Puppeteer Sharp ports; primary source of API design and breaking changesmicrosoft/playwright-dotnet— Alternative .NET browser automation library with similar goals but using Playwright architecture; shared target audienceSeleniumHQ/selenium— Established .NET web testing framework using WebDriver protocol; competitor for testing-focused use caseschromium/chromium— The Chromium project that provides the DevTools Protocol specification and binary that Puppeteer Sharp automateshardkoded/docfx-template— Custom DocFX template used to generate Puppeteer Sharp's published documentation site
🪄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.
Implement BiDi feature parity tests with upstream Puppeteer
The repo has a SKILL.md file for 'implement-bidi-feature' (.claude/skills/implement-bidi-feature/SKILL.md) indicating active BiDi protocol work, but there's no dedicated test suite visible in the file structure. The .NET implementation should have comprehensive tests mirroring the upstream Node.js Puppeteer BiDi test coverage to ensure protocol compliance and catch regressions early.
- [ ] Review upstream Puppeteer BiDi test cases from https://github.com/puppeteer/puppeteer
- [ ] Create src/PuppeteerSharp.Tests/BrowserContextBiDiTests.cs for BiDi-specific browser context operations
- [ ] Create src/PuppeteerSharp.Tests/PageBiDiTests.cs for BiDi page interactions and protocol messages
- [ ] Add test cases for BiDi-only features (e.g., network interception, script evaluation over BiDi)
- [ ] Ensure tests run in CI pipeline via .github/workflows/dotnet.yml
Add comprehensive AOT (Ahead-of-Time) compilation tests
The docfx_project/docs/AOT.md file exists, indicating AOT support is documented, but there's no dedicated GitHub workflow or test project for validating AOT compatibility. Adding AOT-specific CI checks would catch breaking changes early (e.g., reflection usage, dynamic type loading) before releases.
- [ ] Create .github/workflows/aot-validation.yml workflow that compiles a test app with PublishAot=true
- [ ] Add a new console app in demos/ (e.g., PuppeteerSharpAotDemo) that exercises core APIs
- [ ] Configure the demo project with .NET AOT-specific settings in its .csproj file
- [ ] Run IlcTrimAnalyzer and validate no trimming warnings are present
- [ ] Add AOT test results to CI status checks
Implement upstream version sync CI workflow for Puppeteer releases
The repo has a SKILL.md for 'implement-puppeteer-release' (.claude/skills/implement-puppeteer-release/SKILL.md) but no GitHub Action appears to automate tracking of upstream Puppeteer.js releases. A workflow that detects new Puppeteer versions and opens PRs with generated change summaries would reduce manual synchronization overhead.
- [ ] Create .github/workflows/upstream-version-check.yml that runs weekly to detect new Puppeteer releases via GitHub API
- [ ] Add logic to parse Puppeteer CHANGELOG and extract breaking/new changes relevant to .NET port
- [ ] Generate a standardized PR template in the workflow that links to upstream changes, affected APIs, and migration notes
- [ ] Post the PR as a draft with labels like 'upstream-sync' and 'needs-review' for maintainer triage
- [ ] Document the workflow process in CONTRIBUTING.md
🌿Good first issues
- Add locator action examples to docfx_project/docs/LocatorActions.md (file exists but is sparse); write 3-5 real-world examples with code snippets for Click, Fill, Type, and Hover patterns
- Implement missing test coverage for Frame class in src/PuppeteerSharp.Tests/FrameTests/; the codebase has FrameTests.cs but several Frame methods (GoToAsync overloads, WaitForFunctionAsync) lack dedicated test cases
- Document Chrome extension loading workflows in docfx_project/docs/ChromeExtension.md; file exists but lacks step-by-step example showing LaunchOptions configuration + manifest.json setup
⭐Top contributors
Click to expand
Top contributors
- @kblok — 93 commits
- @github-actions[bot] — 4 commits
- @jsneedles — 1 commits
- @IliaBrahinets — 1 commits
- @albyrock87 — 1 commits
📝Recent commits
Click to expand
Recent commits
f0beb96— Fix #3448: correct CDP_ONLY condition check and missing using guards (#3449) (kblok)d9543bd— fix: disable WebUIReloadButton experiment in Chrome launcher (#3438) (kblok)76b765a— feat(webmcp): add UntrustedContent annotation support (#3442) (kblok)feb2b9a— fix: roll to Firefox 150.0.1 (upstream puppeteer PR #14923) (#3447) (kblok)e5294cb— feat: implement URL allowlist for network restrictions and fix offline flag (upstream #14897, #14931) (#3445) (kblok)503de73— fix: roll to Chrome 148.0.7778.97 (upstream PR #14929) (#3446) (kblok)08e3039— fix: do not open DevTools if it is already open (#3443) (kblok)63e41d5— Update sponsors (#3444) (github-actions[bot])316d223— Update sponsors (#3436) (github-actions[bot])066f29d— Update sponsors (#3434) (github-actions[bot])
🔒Security observations
The codebase shows moderate security posture with some concerns primarily in dependency management. Key issues include: (1) outdated/inconsistent JavaScript framework versions (Bootstrap 3/5 duplication, jQuery); (2) reliance on a community GitHub fork instead of an npm-published package; (3) potential for XSS vulnerabilities in the documentation templating system. The .NET backend (Puppeteer Sharp) was not analyzed due to file structure limitations, but the Node.js/JavaScript portions of the documentation build system should be hardened. No hardcoded secrets were detected in visible configuration files. Recommended actions: consolidate dependency versions, migrate to official npm packages, implement automated security scanning in CI/CD, and conduct a thorough npm audit.
- High · Outdated jQuery Dependency with Known Vulnerabilities —
docfx_project/package.json - jquery: 3.7.0. The package.json specifies jQuery 3.7.0, which is pinned to an exact version. While 3.7.0 is relatively recent, jQuery has a history of XSS vulnerabilities. The dependency is used in the documentation template system which could be exposed to untrusted input. Fix: Ensure jQuery is kept up to date and monitor security advisories. Consider using a more modern approach than jQuery for DOM manipulation if possible. Run 'npm audit' regularly to identify vulnerabilities. - Medium · Highlight.js Multiple Versions Inconsistency —
docfx_project/package.json - highlight.js dependencies. The package.json specifies both '@default/highlight.js@11.8.0' and 'highlight.js@11.9.0'. This version inconsistency could lead to unexpected behavior or duplicate code bundles, creating maintenance and security issues. Fix: Consolidate to a single version of highlight.js. Remove the @default scoped version and use the latest stable version consistently across the project. - Medium · Bootstrap Version Inconsistency —
docfx_project/package.json - bootstrap dependencies. The package.json specifies both '@default/bootstrap@3.4.1' (Bootstrap 3) and 'bootstrap@5.3.2' (Bootstrap 5). This creates confusion, increases bundle size, and may introduce CSS conflicts or security issues from outdated Bootstrap 3. Fix: Migrate entirely to Bootstrap 5.3.2 and remove Bootstrap 3 dependencies. Update documentation templates accordingly. - Medium · Unvetted Custom Fork Dependency —
docfx_project/package.json - @default/twbs-pagination. The package.json includes a dependency on a GitHub fork: '@default/twbs-pagination@josecebe/twbs-pagination#1.3.1'. This bypasses npm registry security checks and may pull from an unmaintained or compromised repository. Fix: Verify the josecebe/twbs-pagination fork is actively maintained and trusted. Consider using the official npm package if available, or vendor the code directly in the repository with proper attribution. - Low · Missing npm Audit Configuration —
docfx_project/package.json. The package.json does not explicitly configure npm audit settings or lock file generation strategy. This could allow installation of packages with known vulnerabilities during CI/CD. Fix: Add npm audit configuration to the build pipeline, enforce locked dependencies with 'npm ci', and regularly run security audits in GitHub Actions workflows. - Low · ESLint Configuration Files Present but Strictness Unknown —
docfx_project/templates/.eslintrc.js. The repository includes ESLint configuration (.eslintrc.js) in templates, but without access to the actual file contents, the security-related lint rules cannot be verified (e.g., no-eval, no-implied-eval). Fix: Ensure ESLint rules include security-focused plugins like 'eslint-plugin-security' and configure rules to prevent XSS and injection vulnerabilities.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.