web-platform-kit

Resolves os, browser, engine and device from the UA string, then refines the result with User-Agent Client Hints when they are available. Everything below is read live from the library running in this page.

$ npm install web-platform-kit

Detection

Parsed from the UA string synchronously, so every field is readable immediately. A value shown as null could not be detected here.

readonly version: string;
get userAgent(): string;
get os(): NameVersionPair<OS>;
get browser(): NameVersionPair<Browsers>;
get engine(): NameVersionPair<Engines>;
get device(): Devices;
get webview(): boolean;
get inAppBrowser(): InAppBrowsers | null;
get node(): boolean;
get standalone(): boolean;

interface NameVersionPair<T> {
    readonly name: T;
    readonly version: string;
}

type OS = 'unknown' | 'windows' | 'macos' | 'android' | 'ios';
type Browsers = 'unknown' | 'chrome' | 'safari' | 'edge' | 'firefox' | 'opera' | 'ie' | 'samsung';
type Engines = 'unknown' | 'edgeHtml' | 'arkWeb' | 'blink' | 'presto' | 'webKit' | 'trident' | 'netFront' | 'khtml' | 'tasman' | 'gecko';
type Devices = 'unknown' | 'mobile' | 'tablet' | 'desktop';
type InAppBrowsers = 'kakaotalk' | 'line' | 'instagram' | 'facebook' | 'naver' | 'daum' | 'band' | 'wechat' | 'twitter' | 'tiktok';

ready / whenReady(callback)

On Chromium the sharpest OS and browser versions come from User-Agent Client Hints, which arrive asynchronously. Both forms fire once the merge is done, and the panel above re-renders with whatever the hints added.

get ready(): Promise<void>;

whenReady(callback: () => void): void;
state

Parsing a custom UA

Assigning userAgent re-parses every field from that string, so you can see how any client resolves without owning the device. reset() drops the override and restores the real environment.

set userAgent(userAgent: string);

reset(): void;

Try iPhone Safari · iPad · KakaoTalk in-app · Windows Chrome · IE 11 · macOS Safari

compareVersion(lhs, rhs)

Dotted-version comparison that reads each segment as a number, so 10.0 ranks above 9.9 where a string compare would not. Missing segments count as zero.

compareVersion(lhs: string, rhs: string): -1 | 0 | 1;