# platform

> The operating system family the browser reports in navigator.platform, such as MacIntel, Win32, Linux x86_64 or iPhone.

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

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

| Field | Value |
| --- | --- |
| Component name | `platform` |
| In the visitorId | yes |
| structuredId group | [browser (engine and build)](https://whiskerjs.com/docs/identifiers/#structuredid) |
| Hashing | plain value; a digest only when longer than 128 characters or not printable ASCII |
| Excluded under | no browser class |
| Inner timeout | 1000 ms |
| Added in | [signalsVersion 1](https://whiskerjs.com/whats-new/) |

> **In plain words:**
>
> Every browser tells web pages a short name for the operating system it runs on, such as `Win32` for Windows or `iPhone`. WhiskerJS records that word as it is. It separates big families of devices from each other and is a useful cross-check: if it disagrees with what your server sees in the request, something may have been changed.

## What it reads

`navigator.platform`, a string.

## How the technique works

The property is read once and reported as it is. An empty string or a value that is not a string gives `unavailable`. If the getter throws, the error reaches the runner and the component reports `blocked`. A value longer than 128 characters or containing a character outside printable ASCII would be hashed; real platform strings are short ASCII and appear in plain text.

## Why it helps

It separates operating system families (Windows, macOS, Linux, Android variants, iPhone, iPad) cheaply. Many values are shared by huge numbers of devices, so it adds little uniqueness, but it is very stable and it is one of the values spoofing tools change. Because it is in the id, a tool that changes it on one visit and not on another changes the id.

On your server, compare it with the platform in the request’s user agent header and, on Chromium, with the `platform` field of [`ua_client_hints`](https://whiskerjs.com/signals/ua-client-hints/). Agreement is the normal case; disagreement is a hint, not proof, since some privacy tools change one value and not the others.

## Stability

Very stable: it changes with the operating system family, not with updates. Browsers freeze some values on purpose; for example Macs report `MacIntel` regardless of the CPU.

## Browser support and what blocks it

Every browser exposes `navigator.platform`, including [Chrome](https://whiskerjs.com/browsers/chrome-desktop/), [Firefox](https://whiskerjs.com/browsers/firefox/), [Safari](https://whiskerjs.com/browsers/safari-macos/), [iOS browsers](https://whiskerjs.com/browsers/safari-ios/) and [Android browsers](https://whiskerjs.com/browsers/chrome-android/). Browsers can freeze or simplify the value for compatibility or privacy; WhiskerJS reports whatever the browser returns. No browser class excludes it.

## Privacy

A coarse operating system family, shared by many users. Your server usually sees the same information in the user agent header.

## How WhiskerJS handles noise and failures

| Status | ruleId | When |
| --- | --- | --- |
| `ok` |   | the platform string |
| `unavailable` | `no_api` | missing, empty or not a string |
| `blocked` | `threw`, `security_error` | the getter throws |
| `excluded` | `caller_excluded` | you excluded it |
| `timed_out` | `timeout`, `aborted` | budget or abort |

Three integrity checks watch this property: [`navigator_own_property`](https://whiskerjs.com/docs/integrity/#navigator_own_property) (defined on the navigator object instead of its prototype), [`native_tampering`](https://whiskerjs.com/docs/integrity/#native_tampering) (its getter does not look native) and [`iframe_mismatch`](https://whiskerjs.com/docs/integrity/#iframe_mismatch) (a fresh iframe reads a different value).

## Example value

In the container test, headless Chromium and Firefox reported `Linux x86_64` and WebKit `Linux aarch64`, all on the same ARM host: the string is what the browser chooses to say, not a hardware measurement. Typical values elsewhere: `MacIntel`, `Win32`, `iPhone`.

## Questions and answers

### Why does an Apple Silicon Mac report MacIntel?

Browsers keep the historic value MacIntel on every Mac for compatibility with old sites. The platform value tells operating system families apart, not CPU types; for the CPU family see cpu_architecture.

### Can platform be faked?

Yes, by an extension or a script. WhiskerJS checks for common overrides: navigator_own_property, native_tampering and iframe_mismatch all look at navigator.platform.

### Should my server compare platform with the User-Agent header?

Yes. A platform of Win32 with a Mac user agent header, or one that disagrees with the ua_client_hints platform, is worth a look.

## Related pages

- [ua_client_hints](https://whiskerjs.com/signals/ua-client-hints/): The platform as Client Hints report it, on Chromium.
- [cpu_architecture](https://whiskerjs.com/signals/cpu-architecture/): x86 or ARM, even when platform says MacIntel.
- [navigator_own_property flag](https://whiskerjs.com/docs/integrity/#navigator_own_property): Fires when platform is defined on the navigator object itself.
- [iframe_mismatch flag](https://whiskerjs.com/docs/integrity/#iframe_mismatch): Compares platform with a clean iframe.
- [Recommended server checks](https://whiskerjs.com/docs/integration/#recommended-server-checks): Consistency with what your server sees.
