PuppeteerSharpToolkit 0.1.0

dotnet add package PuppeteerSharpToolkit --version 0.1.0
                    
NuGet\Install-Package PuppeteerSharpToolkit -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="PuppeteerSharpToolkit" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="PuppeteerSharpToolkit" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="PuppeteerSharpToolkit" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add PuppeteerSharpToolkit --version 0.1.0
                    
#r "nuget: PuppeteerSharpToolkit, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package PuppeteerSharpToolkit@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=PuppeteerSharpToolkit&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=PuppeteerSharpToolkit&version=0.1.0
                    
Install as a Cake Tool

PuppeteerSharpToolkit

PuppeteerSharpToolkit is a high-performance, AOT-friendly plugin toolkit for PuppeteerSharp. It’s a modern reimagining of the PuppeteerExtraSharp pattern with a new entry point (PluginManager), focused on trimming- and AOT-safe code, reduced allocations, and startup speed. It is not a drop-in replacement for PuppeteerExtraSharp; APIs and behaviors have been redesigned for performance and clarity.

Why this package exists

  • Updated core: Bumps PuppeteerSharp dependencies to a more modern stack.
  • .NET 9 support: Targets .NET 9, unlocking ahead-of-time (AOT) compilation and aggressive trimming for small, fast binaries.
  • Performance-first design: Rewritten internals to avoid reflection and embedded DLL tricks; optimized for minimal allocations and startup cost.
  • Dropped RestSharp: No longer depends on RestSharp.
  • Dropped NewtonSoftJson: No longer uses NewtonSoft - System.Text.Json is the new king.

Quickstart

// Initialize the plugin manager
var manager = new PluginManager();

// Register plugins (dependencies first)
manager.Register(new AnonymizeUaPlugin());

// Launch the browser with plugins wired
await using var browser = await manager.LaunchAsync(new LaunchOptions { Headless = true });
await using var page = await browser.NewPageAsync();
await page.GoToAsync("https://example.com");
await page.ScreenshotAsync("example.png");

Plugin list

  • Stealth Plugins – Various evasion techniques to make headless detection harder.
  • Anonymize UA Plugin – Anonymizes the user-agent on all pages.
  • ReCAPTCHA Plugin – Solves reCAPTCHAs automatically.
  • Block Resources Plugin – Blocks images, documents, and other resource types to speed up navigation.

API

Stealth Plugins

Stealth related plugins are made for evading detection, usually by injecting scripts at specific times at which websites try to detect bots.

The available evasion plugins are the following: ChromeAppPlugin, ChromeSciPlugin, CodecPlugin, ContentWindowPlugin, EvasionPlugin, HardwareConcurrencyPlugin, LanguagesPlugin, LoadTimesPlugin, OutDimensionsPlugin, PermissionsPlugin, StackTracePlugin, UserAgentPlugin, VendorPlugin, WebDriverPlugin, WebGLPlugin.

In this example we'll use ChromeSciPlugin which patches "chrome.app" and some other chrome APIs that are used by bot detection scripts.

var manager = new PluginManager();
manager.Register(new ChromeSciPlugin());

// Continue with browser and page

To make life a bit easier, Stealth is a static class that provides some static methods:

PuppeteerPlugin[] GetStandardEvasions(params PuppeteerPlugin[] pluginOverride);
// Which returns an array of most stealth plugins.
// The override allows you to initialize any that you with custom arguments
// Any override that you supply will be used instead of calling the default plugin ctor

Task RegisterUtilsAsync(IPage page);
// This function register `utils.js` on a page, it is required by some scripts
// You could also use it if you implement your own plugin, which injects a script
// ... that can rely on `utils.js`

So in essence you could register a suite of stealth plugins in one go:

var manager = new PluginManager();
manager.Register(Stealth.GetStandardEvasions());

AnonymizeUaPlugin

AnonymizeUaPlugin is used to transform the user agent on any page as soon as it launches.

// Initialize the plugin manager
var manager = new PluginManager();
// Initialize the plugin
var plugin = new AnonymizeUaPlugin();
// Register the plugin
manager.Register(plugin);
// by default it will replace headless with regular chrome
// and set platform to windows
// you can also add your own custom transformation at any time by changing the function
plugin.UserAgentTransformer = ua => "whatever";
// Initialize browser and page + continue with whatever else

RecaptchaPlugin

  • Anti-Captcha provider is disabled pending better solution for their requirement to get recaptcha key.
  • 2Captcha provider is disabled pending tests using their API to ensure stability.

RecaptchaPlugin is used in conjunction with Recaptcha solving providers, at this state AntiCaptchaProvider and TwoCaptchaProvider are supported, but this is extensible so you add your own.

The following is an example with AntiCaptcha

// have HttpClient instance ready (it is used to send the requests)
using var client = new HttpClient(); // initialization as example
                                     // best practices will use a factory/singleton
// Initialize the plugin manager
var manager = new PluginManager();
// Initialize the provider (HttpClient, userKey, ProviderOptions)
var provider = new AntiCaptchaProvider(client, "sampleKey", ProviderOptions.Default);
// Default provider options can be used or inferred if omitted.
// Initialize plugin
var plugin = new RecaptchaPlugin(provider);
// Register the plugin
manager.Register(plugin);
// Initialize browser and page
await using var browser = await manager.LaunchAsync();
await using var page = await browser.NewPageAsync();
// go to page with captcha
await page.GoToAsync("https://patrickhlauke.github.io/recaptcha/");
// now solve captcha at page
await plugin.SolveCaptchaAsync(page); // Also accepts proxyStr and cancellationToken.

For 2captcha simply use the TwoCaptchaProvider instead.

BlockResourcesPlugin

This plugin is used to blocks page resources in Puppeteer requests (img, documents etc.)

// Initialize the plugin manager
var manager = new PluginManager();
// Initialize the plugin
var plugin = new BlockResourcesPlugin();
// Register the plugin
manager.Register(plugin);
// Initialize browser and page
await using var browser = await manager.LaunchAsync();
await using var page = await browser.NewPageAsync();
// Create a rule
var blockGoogle = new BlockRule() {
    SitePattern = new Regex("google"), // SitePattern applies only to specific urls by pattern
                                       // You can also point it to a GeneratedRegex
    IPage = page, // it will affect this instance of the page
    ResourceType = ResourceType.Scripts // Block scripts
};
// Add rule
plugin.AddRule(blockGoogle);

You can also inspect rules on the plugin, as well as add or remove rules at any point. removing rules uses a Func<BlockRule, bool> predicate to select the rules to remove.

Core API

Caveats / Testing

RecaptchaPlugin is a clean abstraction, and the tests are mainly testing the specific providers, these tests require having API keys for said providers.

To set the API keys, dotnet user secrets is used, it must be configured when inside the test project directory:

dotnet user-secrets set [secretName] [secretValue]

All Recaptcha tests are marked as Explicit and will not execute when running the full test suite (unless specifically asked for), this is to avoid burning API usage.

If you do want to run them use:

dotnet run --explicit on/only

Also, each provider test will be skipped automatically if the required API key wasn't found in user secrets, so if for example you only have an API key for AntiCaptcha - only the tests related to this provider will run.

Contribution

Patches, performance improvements, and fixes are welcome. Focus is on keeping the core lean and compatible with modern .NET publishing scenarios.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 133 8/13/2025
0.1.0-rc.2 115 8/13/2025
0.1.0-rc.1 120 8/13/2025

- Initial release