# webgl_vendor

> The GPU vendor string the browser reports through WebGL, read the same way as the renderer.

Source: https://whiskerjs.com/signals/webgl-vendor/ (last updated 2026-10-26)

**webgl_vendor at a glance (from the library code, signalsVersion 9)**

| Field | Value |
| --- | --- |
| Component name | `webgl_vendor` |
| In the visitorId | yes |
| structuredId group | [gpu (graphics)](https://whiskerjs.com/docs/identifiers/#structuredid) |
| Hashing | plain value; a digest only when longer than 128 characters or not printable ASCII |
| Excluded under | Brave (brave_farbling); Firefox resistFingerprinting (firefox_rfp); Tor Browser and Mullvad Browser (rfp_hardened) |
| Inner timeout | 1000 ms |
| Added in | [signalsVersion 1](https://whiskerjs.com/whats-new/) |

> **In plain words:**
>
> Next to the GPU name, browsers report who made the graphics driver, for example Apple, Intel or NVIDIA, sometimes wrapped in the browser’s own name. WhiskerJS reads this short text as it is. On its own it only separates a few big vendors; together with the renderer name it describes the graphics setup.

## What it reads

The method is the same as for [`webgl_renderer`](https://whiskerjs.com/signals/webgl-renderer/), on the shared WebGL 1 context:

- outside Firefox, `getParameter(UNMASKED_VENDOR_WEBGL)` from the `WEBGL_debug_renderer_info` extension;
- if that is missing or empty, the plain `gl.VENDOR` value;
- in Firefox the extension is never requested (it would print a console warning), and the plain value is used.

## How the technique works

WebGL offers a “masked” vendor (often a generic browser name such as “WebKit”) and, through the debug extension, the underlying driver vendor. WhiskerJS prefers the unmasked value, falls back to the plain one, and reports the text unless it is longer than 128 characters or not printable ASCII, in which case it is hashed. The raw value is also used, inside the library only, by the [`software_renderer`](https://whiskerjs.com/docs/integrity/#software_renderer) check: a vendor such as “Brian Paul” with Mesa offscreen rendering points to software rendering.

## Why it helps

It splits devices by GPU vendor and graphics layer, and it is a simple cross-check: an Apple GPU vendor with a Windows platform, or a software vendor on what claims to be a phone, is worth a look on your server. It is in the `gpu` group.

## Stability

Very stable: it changes when the GPU in use changes, when hardware acceleration is switched, or when a browser update changes how its graphics layer names the vendor.

## Browser support and what blocks it

- `ok` wherever WebGL 1 is available. Typical values: `Google Inc. (Apple)` in Chrome on a Mac, `Apple Inc.` in the headless WebKit test run used for these pages, `Google Inc. (Google)` with SwiftShader in headless Chromium.
- [Brave](https://whiskerjs.com/browsers/brave/): `excluded` / `brave_farbling` (since signalsVersion 6): since Brave 1.93 every user reports one generic vendor string.
- [Firefox resistFingerprinting](https://whiskerjs.com/browsers/firefox-rfp-and-tor/): `excluded` / `firefox_rfp`; [Tor Browser and Mullvad Browser](https://whiskerjs.com/browsers/firefox-rfp-and-tor/): `excluded` / `rfp_hardened`.
- No WebGL: `unavailable` / `no_context`.

## Privacy

A short vendor name, read without permission or prompt, never sent by WhiskerJS. Values outside printable ASCII or over 128 characters leave only as a digest.

## How WhiskerJS handles noise and failures

| Status | ruleId | When |
| --- | --- | --- |
| `ok` | none | plain text (or a digest when long or unusual) |
| `unavailable` | `no_value` | both values were empty |
| `unavailable` | `no_document`, `no_api`, `no_context` | no document, no `getContext`, no WebGL |
| `unavailable` | `no_digest` | needed hashing without Web Crypto |
| `blocked` | `security_error`, `threw` | `getParameter` threw |
| `excluded` | `brave_farbling`, `firefox_rfp`, `rfp_hardened`, `caller_excluded` | exclusion table or your list |
| `timed_out` | `timeout`, `aborted` | 1000 ms inner timeout, budget, abort |

## Example value

From a headless WebKit test browser in a container:

```json
"webgl_vendor": { "status": "ok", "value": "Apple Inc.", "hashed": false }
```

## Questions and answers

### Why does Chrome report Google Inc. as the vendor?

Chromium browsers draw WebGL through their ANGLE layer, so the unmasked vendor usually reads like Google Inc. followed by the real GPU vendor in brackets, for example Google Inc. (Apple).

### Is webgl_vendor useful on its own?

It tells apart only a handful of vendors. Its value is in combination with webgl_renderer and the rest of the gpu group, and as a consistency check against the platform.

## Related pages

- [webgl_renderer](https://whiskerjs.com/signals/webgl-renderer/): The GPU name from the same extension.
- [webgpu](https://whiskerjs.com/signals/webgpu/): The adapter vendor through WebGPU.
- [software_renderer flag](https://whiskerjs.com/docs/integrity/#software_renderer): Also checks the vendor string.
- [Firefox resistFingerprinting and Tor](https://whiskerjs.com/browsers/firefox-rfp-and-tor/): Where it is excluded.
