![]() |
VOOZH | about |
dotnet add package Soenneker.Playwrights.Extensions.Stealth --version 4.0.96
NuGet\Install-Package Soenneker.Playwrights.Extensions.Stealth -Version 4.0.96
<PackageReference Include="Soenneker.Playwrights.Extensions.Stealth" Version="4.0.96" />
<PackageVersion Include="Soenneker.Playwrights.Extensions.Stealth" Version="4.0.96" />Directory.Packages.props
<PackageReference Include="Soenneker.Playwrights.Extensions.Stealth" />Project file
paket add Soenneker.Playwrights.Extensions.Stealth --version 4.0.96
#r "nuget: Soenneker.Playwrights.Extensions.Stealth, 4.0.96"
#:package Soenneker.Playwrights.Extensions.Stealth@4.0.96
#addin nuget:?package=Soenneker.Playwrights.Extensions.Stealth&version=4.0.96Install as a Cake Addin
#tool nuget:?package=Soenneker.Playwrights.Extensions.Stealth&version=4.0.96Install as a Cake Tool
👁 alternate text is missing from this package README image
👁 alternate text is missing from this package README image
👁 alternate text is missing from this package README image
👁 alternate text is missing from this package README image
A .NET extension library for Microsoft Playwright that makes browser automation harder to detect. It applies launch-argument hardening, context shaping, and init-script evasions so Chromium sessions look more like normal user sessions.
You might also be interested in:
dotnet add package Soenneker.Playwrights.Extensions.Stealth
Playwright.LaunchStealthChromium().browser.CreateStealthContext().using Microsoft.Playwright;
using Soenneker.Playwrights.Extensions.Stealth;
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.LaunchStealthChromium(new BrowserTypeLaunchOptions
{
Headless = true,
Channel = "chromium"
});
var browserContext = await browser.CreateStealthContext();
var page = await browserContext.NewPageAsync();
If Chromium is already running remotely, for example in a Docker sidecar, connect with the endpoint overload:
using Microsoft.Playwright;
using Soenneker.Playwrights.Extensions.Stealth;
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.LaunchStealthChromium(
"ws://playwright:3000/",
new BrowserTypeConnectOptions());
var context = await browser.CreateStealthContext();
var page = await context.NewPageAsync();
In endpoint mode, stealth launch arguments are not applied because the remote browser is already running. Stealth still applies at the browser-context level via CreateStealthContext().
Pass an optional proxy into CreateStealthContext:
var context = await browser.CreateStealthContext(new Proxy
{
Server = "http://proxy.example.com:8080",
Username = "user",
Password = "secret"
});
The defaults are recommended, but if you want to tune options further:
using Microsoft.Playwright;
using Soenneker.Playwrights.Extensions.Stealth;
using Soenneker.Playwrights.Extensions.Stealth.Options;
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.LaunchStealthChromium(
new BrowserTypeLaunchOptions { Headless = true },
new StealthLaunchOptions
{
Channel = "chrome",
IncludeNoSandboxArgument = false,
IgnoreDetectableDefaultArguments = true,
AdditionalIgnoredDefaultArguments = ["--disable-features=DialMediaRouteProvider"],
AdditionalArguments = ["--disable-features=Translate"]
});
var context = await browser.CreateStealthContext(
new BrowserNewContextOptions
{
// Optionally specify a UserAgent
UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36"
},
new StealthContextOptions
{
NormalizeDocumentHeaders = true,
InjectClientHintHeaders = true,
WarmupSpeechVoices = true,
PatchFunctionToString = false,
EnableCdpDomainHardening = true,
DisableConsoleDomain = true,
DisableRuntimeDomain = false,
Surfaces = new StealthSurfaceOptions
{
NavigatorProfile = StealthSurfaceMode.Native,
NavigatorPlugins = StealthSurfaceMode.Native,
Screen = StealthSurfaceMode.Native,
Battery = StealthSurfaceMode.Native,
UserAgentData = StealthSurfaceMode.Native,
PermissionsQuery = StealthSurfaceMode.Native,
DocumentFonts = StealthSurfaceMode.Native,
Canvas = StealthSurfaceMode.Native,
MediaDevices = StealthSurfaceMode.Native
},
AdditionalHttpHeaders = new Dictionary<string, string>
{
["DNT"] = "1"
}
});
You can apply the same stealth behavior to a context you already created:
var context = await browser.NewContextAsync();
await context.ApplyStealthAsync();
| Area | Description |
|---|---|
| Launch options | Normalizes Chromium args with stealth-oriented defaults: ensures --disable-blink-features=AutomationControlled, forces --headless=new when headless, and can strip detectable Playwright default args via IgnoreDefaultArgs. |
| Channel selection | If BrowserTypeLaunchOptions.Channel is unset, StealthLaunchOptions.Channel is used (default chromium). Set Channel = "chrome" (or pass BrowserTypeLaunchOptions.Channel) when you want the installed Google Chrome channel. |
| Hardware profile | Each context gets a random but internally consistent Windows/Chrome profile: CPU cores, memory, viewport, DPR, Chrome version, timezone, locale/languages, and WebGL identity. Randomized geolocation is available as an explicit opt-in. |
| Context shaping | Sets coherent User-Agent, language headers, timezone, viewport, DPR, and color scheme from the same generated profile. Generated Chromium User-Agents follow UA reduction (Chrome/<major>.0.0.0>), and a caller-supplied BrowserNewContextOptions.UserAgent is propagated into the derived Client Hints fields when header injection is enabled. Fingerprint surfaces such as navigator profile getters, plugins/mimeTypes, screen values, battery, navigator.userAgentData, navigator.permissions.query(), document.fonts, canvas, and media devices can each be left native, spoofed, or disabled. |
| Speech voices | The injected init script can warm up native speechSynthesis voices before page scripts run, reducing the chance that a site observes an empty or not-yet-populated voice list. |
| Request shaping | Registers early context routing so top-level document navigations get normalized navigation headers before the first page load. |
| CDP hardening (optional) | Can disable selected Chromium CDP domains (e.g. Console, optionally Runtime) per page to reduce protocol surface. |
| Init script | Injected before page load to reduce automation signals: hides navigator.webdriver; aligns navigator/screen/window (e.g. hardwareConcurrency, deviceMemory, platform, vendor, languages, plugins, dimensions, DPR); Client Hints and navigator.userAgentData; window.chrome; permissions/connection/battery/media/geolocation shims; timezone via Intl; canvas noise; WebGL vendor/renderer spoofing; WebRTC host-candidate stripping. |
Channel, RemoveDetectableArguments, IncludeNoSandboxArgument, IgnoreDetectableDefaultArguments, AdditionalArguments, AdditionalIgnoredDefaultArguments).Proxy, AdditionalHttpHeaders, InjectClientHintHeaders, NormalizeDocumentHeaders, AlignColorScheme, RandomizeGeolocation, WarmupSpeechVoices, PatchFunctionToString, Surfaces, EnableCdpDomainHardening, DisableConsoleDomain, DisableRuntimeDomain).StealthSurfaceMode (Native, Spoofed, Disabled) for NavigatorProfile, NavigatorPlugins, Screen, Battery, UserAgentData, PermissionsQuery, DocumentFonts, Canvas, MediaDevices, and WebGl.| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
Showing the top 2 NuGet packages that depend on Soenneker.Playwrights.Extensions.Stealth:
| Package | Downloads |
|---|---|
|
Soenneker.Cloudflare.Downloader
Allows for navigating and downloading from Cloudflare sites in under-attack mode |
|
|
Soenneker.Playwrights.Crawler
A configurable Playwright crawler with rich stealth and control options. |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 4.0.96 | 0 | 6/19/2026 |
| 4.0.95 | 0 | 6/19/2026 |
| 4.0.94 | 0 | 6/18/2026 |
| 4.0.93 | 291 | 6/17/2026 |
| 4.0.92 | 119 | 6/17/2026 |
| 4.0.91 | 330 | 6/16/2026 |
| 4.0.90 | 79 | 6/16/2026 |
| 4.0.89 | 552 | 6/13/2026 |
| 4.0.88 | 86 | 6/13/2026 |
| 4.0.87 | 718 | 6/10/2026 |
| 4.0.86 | 640 | 6/10/2026 |
| 4.0.85 | 572 | 6/9/2026 |
| 4.0.84 | 1,052 | 6/6/2026 |
| 4.0.83 | 322 | 6/6/2026 |
| 4.0.82 | 232 | 6/6/2026 |
| 4.0.81 | 170 | 6/5/2026 |
| 4.0.80 | 112 | 6/5/2026 |
| 4.0.79 | 136 | 6/5/2026 |
| 4.0.78 | 1,903 | 5/22/2026 |
| 4.0.77 | 942 | 5/13/2026 |
Update dependency Soenneker.Extensions.Task to 4.0.123 (#319)