web-platform-kit
v0.0.4
Published
TypeScript user-agent & platform detection — OS, browser, engine, and device parsing with User-Agent Client Hints (high-entropy) merging, version comparison, WebView/PWA/Node detection.
Maintainers
Readme
web-platform-kit
A tiny TypeScript user-agent & platform detector — resolves OS, browser, engine, and device from the UA string, then refines the result with User-Agent Client Hints (high-entropy) when available.
npm install web-platform-kitAPI at a glance
PlatformKit is a singleton. All detection fields are getters.
| Member | Type | Description |
|------------------------------------| --- | --- |
| PlatformKit.version | string | The installed package version |
| PlatformKit.ready | Promise<void> | Resolves once async UA Client Hints have merged in |
| PlatformKit.userAgent | string (get/set) | Read the active UA string, or set one to parse a custom UA |
| PlatformKit.os | { name, version } | name: unknown \| windows \| macos \| android \| ios |
| PlatformKit.browser | { name, version } | name: unknown \| chrome \| safari \| edge \| firefox \| opera \| ie \| samsung |
| PlatformKit.engine | { name, version } | name: blink \| webKit \| gecko \| presto \| trident \| … |
| PlatformKit.device | string | unknown \| mobile \| desktop |
| PlatformKit.webview | boolean | Whether running inside a WebView |
| PlatformKit.node | boolean | Whether running under Node.js |
| PlatformKit.standalone | boolean | Whether launched as an installed PWA |
| PlatformKit.compareVersion(a, b) | -1 \| 0 \| 1 | Numeric dotted-version comparison (named export) |
About
ready: on Chromium, the most accurate OS/browser version comes from User-Agent Client Hints, which resolve asynchronously. Read fields afterawait PlatformKit.readyfor best accuracy; before it resolves you still get a synchronous result parsed from the UA string.
ESM
import PlatformKit from 'web-platform-kit'
// Synchronous (UA-string based) — available immediately
console.log(PlatformKit.os) // { name: 'ios', version: '17.4' }
console.log(PlatformKit.browser) // { name: 'safari', version: '17.4' }
console.log(PlatformKit.device) // 'mobile'
// Refined with Client Hints (Chromium) — await first
await PlatformKit.ready
console.log(PlatformKit.os.version) // full platform version on Chromium
// Version gate
if (PlatformKit.compareVersion(PlatformKit.os.version, '15.0') >= 0) {
// iOS 15+
}CommonJS
The bundle is built with exports: "named", so the singleton lives under .default:
const { default: PlatformKit } = require('web-platform-kit')
console.log(PlatformKit.browser.name, PlatformKit.browser.version)UMD (browser <script>)
The global PlatformKit is a namespace object. The singleton is PlatformKit.default;
the helper is PlatformKit.compareVersion.
<script src="https://unpkg.com/web-platform-kit/dist/platform-kit.umd.min.js"></script>
<script>
var p = window.PlatformKit.default
document.body.dataset.os = p.os.name
document.body.dataset.browser = p.browser.name
if (p.webview) {
console.log('running inside a WebView')
}
</script>TypeScript
The { name, version } shape is exported as NameVersionPair<T>; the singleton
shape is PlatformKitInstance. The os / browser / engine / device name
unions are exported too (OS, Browsers, Engines, Devices).
import PlatformKit, {
type OS,
type NameVersionPair,
} from 'web-platform-kit'
const os: NameVersionPair<OS> = PlatformKit.os
function isModernSafari(): boolean {
return PlatformKit.browser.name === 'safari'
&& PlatformKit.compareVersion(PlatformKit.browser.version, '16.0') >= 0
}Parsing a custom UA string
Set userAgent to parse an arbitrary string — useful server-side or in tests.
Setting a custom UA parses purely from that string (no Client Hints merge).
import PlatformKit from 'web-platform-kit'
PlatformKit.userAgent = 'Mozilla/5.0 (Linux; Android 14; Pixel 8) ' +
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Mobile Safari/537.36'
console.log(PlatformKit.os) // { name: 'android', version: '14' }
console.log(PlatformKit.browser) // { name: 'chrome', version: '124.0' }Note:
userAgentis shared singleton state — setting it changes detection globally for every reader. RestorePlatformKit.userAgentif other code relies on the real environment.
Notes
- Detection is best-effort. User agents are spoofable and inconsistent across vendors; treat the result as a strong hint, not ground truth. Prefer feature detection for capability decisions where possible.
- Client Hints are Chromium-only and async. Non-Chromium browsers resolve
readyimmediately with UA-string parsing;os.versiongranularity is limited to what the UA string exposes there. - iPadOS reports as desktop. iPadOS Safari sends a macOS UA; this library
re-classifies it as
ioswhennavigator.standaloneis present andmaxTouchPoints > 2, but edge cases remain. .defaultin CJS/UMD is a consequence of keeping both a default and named exports. To drop it, switch the entry to fully-named exports and rebuild.
