Free tools Windows power users keep installed
One-click scans. No signup required.
Yes. Headless Chrome can render WebGL without a physical GPU by using Chromium’s CPU-based SwiftShader renderer. For an explicit WebGL fallback, launch Chromium with --use-gl=angle, --use-angle=swiftshader-webgl and --enable-unsafe-swiftshader, then verify that the page actually creates a WebGL context and finishes drawing before you capture the image.
chrome --headless
--use-gl=angle
--use-angle=swiftshader-webgl
--enable-unsafe-swiftshader
--screenshot=shot.png https://stripe.com
Replace the URL with the page you need to render. The switches select software WebGL; they do not prove that your application rendered correctly. Context creation, page readiness, viewport, device scale factor and the final pixels must all be checked.
What SwiftShader does in headless Chrome
SwiftShader is Chromium’s CPU implementation of Vulkan and OpenGL ES. It performs graphics work in software, so a discrete or integrated graphics processor is not required for WebGL rendering.
Chromium documents two related but different configurations:
#1 Best Overall
- Powered by Radeon RX 9070 XT
- WINDFORCE Cooling System
- Hawk Fan
- Server-grade Thermal Conductive Gel
- RGB Lighting
- SwiftShader as the OpenGL ES driver:
--use-gl=angle --use-angle=swiftshader. This routes the browser’s OpenGL ES path through SwiftShader. - SwiftShader as the WebGL fallback:
--use-gl=angle --use-angle=swiftshader-webgl, with an explicit--enable-unsafe-swiftshaderopt-in.
Those modes are not interchangeable names for one setting. If the application specifically needs WebGL to work in an environment without usable GPU drivers, use the documented swiftshader-webgl fallback first.
Before you launch Chrome
Record the software and host
Use a current Chrome or Chromium executable and record its version, operating system, architecture and automation-library version with each result. SwiftShader behavior and command-line switches can change between browser releases.
Make sure the process can write output
The Chrome user-data directory and destination image directory must be writable by the account running the job. In CI, use a temporary profile for parallel jobs so separate workers do not lock the same profile.
Choose a trusted-page boundary
--enable-unsafe-swiftshader reduces security guarantees. Chromium identifies JIT-compiled code in the GPU process as a security risk and describes this opt-in for developer testing on headless or unsupported-GPU systems, not arbitrary untrusted content. Do not combine it with a browser that navigates freely to attacker-controlled pages.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesLaunch the explicit software-WebGL fallback
Direct Chrome command
chrome --headless
--use-gl=angle
--use-angle=swiftshader-webgl
--enable-unsafe-swiftshader
--window-size=1440,900
--screenshot=shot.png https://stripe.com
--headless starts Chrome without a visible window. The window size controls the CSS viewport used for the capture; set it to the dimensions your application expects. Add a device-scale-factor option in your automation library when you need retina-sized output.
Rank #2
- Powered by the NVIDIA Blackwell architecture and DLSS 4
- Powered by GeForce RTX 5070 Ti
- Integrated with 16GB GDDR7 256bit memory interface
- PCIe 5.0
- WINDFORCE cooling system
Puppeteer
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
headless: true,
args: [
'--use-gl=angle',
'--use-angle=swiftshader-webgl',
'--enable-unsafe-swiftshader',
'--window-size=1440,900'
],
defaultViewport: { width: 1440, height: 900, deviceScaleFactor: 1 }
});
const page = await browser.newPage();
await page.goto('https://stripe.com', { waitUntil: 'networkidle2', timeout: 90000 });
await page.screenshot({ path: 'shot.png', fullPage: true });
await browser.close();
})();
Puppeteer’s headless: true uses Chrome’s unified headless mode. Keep the explicit flags in args; a successful browser launch alone does not establish that WebGL is available.
Selenium with Python
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless')
options.add_argument('--use-gl=angle')
options.add_argument('--use-angle=swiftshader-webgl')
options.add_argument('--enable-unsafe-swiftshader')
options.add_argument('--window-size=1440,900')
driver = webdriver.Chrome(options=options)
try:
driver.get('https://stripe.com')
driver.save_screenshot('shot.png')
finally:
driver.quit()
Selenium passes the same switches to Chrome. If your driver and browser major versions are incompatible, fix that pairing before investigating WebGL.
Verify that WebGL actually rendered
Test the context in the page, not just the process exit code. This JavaScript returns the renderer strings and reports whether WebGL 2 or WebGL 1 was created:
const result = await page.evaluate(() => {
const canvas = document.createElement('canvas');
const gl2 = canvas.getContext('webgl2');
const gl = gl2 || canvas.getContext('webgl');
if (!gl) return { ok: false, reason: 'No WebGL context' };
const debug = gl.getExtension('WEBGL_debug_renderer_info');
return {
ok: true,
version: gl.getParameter(gl.VERSION),
renderer: debug
? gl.getParameter(debug.UNMASKED_RENDERER_WEBGL)
: gl.getParameter(gl.RENDERER)
};
});
console.log(result);
Treat ok: false as a rendering failure and provide the application’s fallback, such as Canvas 2D or a user-facing “WebGL unavailable” message. A non-null context still does not guarantee that asynchronous textures, shaders or animation frames completed.
Wait for the application’s own completion signal
The most reliable readiness condition is an application-defined selector or JavaScript promise. For example, wait for a canvas attribute your page sets after drawing:
Rank #3
- AI Performance: 767 AI TOPS
- OC mode: 2632 MHz (OC mode)/ 2602 MHz (Default mode)
- Powered by the NVIDIA Blackwell architecture and DLSS 4
- Axial-tech fan design features a smaller fan hub that facilitates longer blades and a barrier ring that increases downward air pressure
- A 2.5-slot design maximizes compatibility and cooling efficiency for superior performance in small chassis
await page.waitForFunction(() => {
const canvas = document.querySelector('#webgl-canvas');
return canvas && canvas.dataset.renderComplete === 'true';
}, { timeout: 30000 });
await page.screenshot({ path: 'shot.png' });
If you do not control the page, combine a selector wait with a bounded delay and inspect the resulting pixels. Network-idle alone can be insufficient because WebGL scenes may continue loading assets or rendering after network requests stop.
Headless mode, hardware acceleration and Linux caveats
Headless does not inherently mean “no GPU.” Current headless Chrome can use a local GPU in some environments. Chromium’s headless behavior commonly forces SwiftShader for consistency; --enable-gpu removes that forced software choice and returns to regular driver selection, but it does not guarantee hardware acceleration.
Recommended Free Tools
On Linux, driver autodetection may require an available X display. Some configurations work with --use-angle=vulkan, while others depend on the installed driver stack and display environment. If your requirement is specifically hardware acceleration, test the actual host rather than assuming a flag will create a GPU.
Do not confuse the separate headless shell
Chrome’s current headless mode is unified with regular Chrome. The former separate implementation is available as chrome-headless-shell beginning with Chrome 132.0.6793.0. Automation examples that launch Chrome directly, Puppeteer with headless: true and Selenium with --headless use the unified mode unless you deliberately install and launch the shell binary.
Software versus hardware rendering
| Factor | SwiftShader WebGL fallback | Hardware path |
|---|---|---|
| Physical GPU | Not required; rendering runs on the CPU. | Requires usable hardware, drivers and a compatible browser configuration. |
| WebGL selection | Explicitly opt in with swiftshader-webgl and enable-unsafe-swiftshader. |
Driver selection is environment-dependent; --enable-gpu only removes forced software selection. |
| Security | The unsafe opt-in lowers security guarantees and is intended for trusted testing pages. | Uses the host’s normal graphics stack, with its own driver and sandbox considerations. |
| Host dependencies | Still depends on a functioning Chrome build and CPU resources; it avoids GPU hardware. | Depends on drivers, display availability and platform-specific configuration. |
| Output and speed | Must be validated for your scene; no general performance result is guaranteed. | May be faster for demanding scenes, but results vary by host and driver. |
Reliability and performance practices
- Pin and report versions: record Chrome, driver, OS and automation-library versions so a changed renderer can be diagnosed.
- Use bounded waits: set navigation and render timeouts, then fail clearly instead of producing a partially drawn image.
- Control viewport and scale: keep viewport dimensions and device scale factor fixed when comparing images.
- Limit concurrency: SwiftShader consumes CPU; too many simultaneous browsers can cause timeouts and inconsistent completion times.
- Check pixels or a completion marker: save a known scene and compare dimensions, alpha behavior and a small set of expected pixels.
- Keep profiles isolated: a temporary user-data directory per worker avoids locks and stale WebGL state.
Troubleshooting
“No WebGL context” or a null context
Confirm all three fallback switches are present, especially --enable-unsafe-swiftshader. Check that the page is not disabling WebGL itself and that you are testing the same Chrome binary your automation library launches. Handle the failure in the application rather than assuming fallback will happen automatically; Chromium’s automatic SwiftShader WebGL fallback is deprecated.
Rank #4
- Powered by the NVIDIA Blackwell architecture and DLSS 4. System Requirements: Minimum 850W PSU with 16-pin 12V-2x6 (12VHPWR) connector required. Verify before purchasing.
- Military-grade components deliver rock-solid power and longer lifespan for ultimate durability. Compatibility: 348mm (13.7") length, 3.6 slots, 4.3 lbs. Confirm case clearance and slot spacing. GPU bracket included.
- Protective PCB coating helps protect against short circuits caused by moisture, dust, or debris
- 3.6-slot design with massive fin array optimized for airflow from three Axial-tech fans
- Phase-change GPU thermal pad helps ensure optimal thermal performance and longevity, outlasting traditional thermal paste for graphics cards under heavy loads
Chrome exits with an unknown-switch error
Verify the executable is Chrome or Chromium, not a different embedded browser, and check its version. Remove obsolete switches one at a time, then confirm the supported equivalents for that build. Do not silently ignore a missing flag when the test depends on software WebGL.
The screenshot is blank or incomplete
Wait for the scene’s own completion signal, not merely page load. Increase the bounded timeout, inspect console errors, verify that textures are same-origin or correctly permitted, and capture at the viewport and device scale factor used by the application.
Linux works locally but fails in CI
Compare the CI image’s Chrome version, shared libraries, CPU limits and display environment. Headless GPU behavior is platform-dependent; a local display or driver may be masking a CI dependency. Use the explicit SwiftShader path when the goal is deterministic software rendering, then verify the context in CI.
The page is untrusted
Do not use --enable-unsafe-swiftshader as a general-purpose browser setting for arbitrary navigation. Restrict URLs, isolate the process and profile, and treat the switch as a test-only trust decision.
Or skip the browser setup
If you need a hosted website capture rather than maintaining Chrome flags and rendering workers, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns PNG, JPEG, WebP or PDF; its cleanup steps can accept consent banners and remove more than 60 known consent platforms, newsletter popups and chat widgets before capture. Each response identifies whether the page was clean, billed or a cache hit: bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Use the API documentation at screenshotneo.com/docs/. The following calls use the documented endpoint:
Best Value
- Next-Gen Intel Arc Graphics: Powered by Intel Arc A580 GPU with Intel Xe HPG microarchitecture, featuring 384 XMX engines for enhanced AI acceleration and content creation.
- High-Performance Memory: 8GB GDDR6 on a 256-bit interface running at 16 Gbps, delivering excellent bandwidth for 1440p gaming and creative workloads.
- Factory Overclocked: Engine clock set at 2000 MHz out of the box, providing optimized performance for smooth gameplay and multimedia tasks.
- Advanced Dual-Fan Cooling: Features a dual-fan design with striped axial fans and an ultra-fit heatpipe for efficient thermal management. 0dB Silent Cooling stops fans completely at low temperatures for silent operation.
- Durable Construction: Includes a stylish metal backplate for enhanced PCB rigidity and a premium aesthetic, backed by ASRock's Super Alloy components for long-term reliability.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also exposes an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. Features include full-page and selector captures, dark mode, device presets, retina scale, custom CSS and JavaScript, waits, request blocking, headers and cookies, geolocation, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, caching with a chosen TTL and a usage API.
| Plan | Allowance and price |
|---|---|
| Free | 1,000 shots/month, no card |
| Starter | $5 for 3,000 shots |
| Growth | $15 for 15,000 shots |
| Pro | $39 for 60,000 shots |
| Scale | $99 for 250,000 shots |
| Business | $249 for 1,000,000 shots |
Yearly billing gives two months free, and every feature is included on every plan. Start with 1,000 free screenshots a month with no card.
Frequently Asked Questions
Can I rely on automatic SwiftShader fallback without the unsafe flag?
No. Chromium documents automatic WebGL fallback as deprecated; context creation may fail instead. Use the explicit fallback switches for a trusted test environment and handle a null context.
Does a successful Chrome launch prove that WebGL rendered?
No. Query WebGL 2 or WebGL 1 in the page, wait for the scene’s completion condition and inspect the captured output.
Should I use SwiftShader’s OpenGL ES mode or WebGL fallback mode?
Use the WebGL fallback switches when the requirement is software WebGL. The OpenGL ES driver setting is a different configuration and should not be substituted without testing the application.
Will enabling GPU make headless Chrome use hardware?
Not necessarily. --enable-gpu removes the forced software choice, but hardware access still depends on the host’s drivers, display environment and browser build.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

