npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@adddog/trivial-user-agent-detector

v0.0.2

Published

> Type-safe, functional user agent detection for modern browsers

Readme

@adddog/trivial-user-agent-detector

Type-safe, functional user agent detection for modern browsers

A comprehensive, zero-dependency library for detecting browsers, devices, capabilities, and features. Built with TypeScript, functional programming principles, and complete immutability.

Features

Browser Detection - Chrome, Firefox, Safari, Edge, Opera with version numbers 📱 Device Detection - Mobile, tablet, desktop, smart TV, console, wearable, XR, embedded 🔧 CPU Architecture - AMD64, ARM64, ARM, ARMHF, IA32, SPARC 🎨 Rendering Engines - Blink, WebKit, Gecko, Trident, EdgeHTML, Presto 💪 Capabilities - Touch, Canvas, WebGL, History API, Fullscreen 🎯 iOS & Android - Specific device and version detection 🔢 Version Comparison - Built-in helpers for browser version checks 🌐 Client Hints - Modern User-Agent Client Hints API support 🎁 100% Type-Safe - Full TypeScript support with strict types 🌳 Tree-Shakeable - Import only what you need 🚫 Zero Dependencies - No external dependencies

Installation

pnpm add @adddog/trivial-user-agent-detector
# or
npm install @adddog/trivial-user-agent-detector
# or
yarn add @adddog/trivial-user-agent-detector

Quick Start

import { createDetector } from "@adddog/trivial-user-agent-detector";

const detector = createDetector();

// Get all detection results at once
const all = detector.detectAll();
console.log(all);

// Or use individual methods
const browser = detector.detectBrowser();
console.log(browser.isChrome);        // true
console.log(browser.chromeVersion);   // 119

const device = detector.detectDevice();
console.log(device.isMobile);         // true
console.log(device.device);           // "mobile"

Browser Version Detection

Detect major browser versions and compare them easily:

const detector = createDetector();
const browser = detector.detectBrowser();

// Version properties
console.log(browser.chromeVersion);   // 119 or false
console.log(browser.firefoxVersion);  // 120 or false
console.log(browser.safariVersion);   // 17 or false
console.log(browser.edgeVersion);     // 119 or false
console.log(browser.operaVersion);    // 105 or false

// Version comparison helpers
if (detector.isBrowserVersionGreaterThanOrEqual(browser.chromeVersion, 100)) {
    console.log("Chrome 100+ detected - feature is supported!");
}

if (detector.isBrowserVersionLessThan(browser.firefoxVersion, 90)) {
    console.log("Loading polyfill for older Firefox");
}

if (detector.isBrowserVersionInRange(browser.safariVersion, 14, 17)) {
    console.log("Safari version is in supported range");
}

// Check for specific version bugs
if (browser.isEdge && detector.isBrowserVersionEqual(browser.edgeVersion, 18)) {
    console.log("Apply Edge 18 workaround");
}

Device Detection

Detect a wide range of device types:

const device = detector.detectDevice();

console.log(device.device); // "desktop" | "mobile" | "tablet" | "smarttv" | "console" | "wearable" | "xr" | "embedded"
console.log(device.isMobile);   // boolean
console.log(device.isTablet);   // boolean
console.log(device.isDesktop);  // boolean

CPU Architecture

Detect the underlying CPU architecture:

const cpu = detector.detectCPU();

console.log(cpu.architecture); // "amd64" | "arm64" | "arm" | "armhf" | "ia32" | "sparc" | "unknown"

Rendering Engine

Detect the browser's rendering engine:

const engine = detector.detectEngine();

console.log(engine.engine); // "Blink" | "WebKit" | "Gecko" | "Trident" | "EdgeHTML" | "Presto" | "unknown"

iOS & Android Detection

Specific detection for mobile operating systems:

const ios = detector.detectIOS();
console.log(ios.isIOS);        // boolean
console.log(ios.isIphone);     // boolean
console.log(ios.isIpad);       // boolean
console.log(ios.isIpod);       // boolean
console.log(ios.IOSVersion);   // number or false

const android = detector.detectAndroid();
console.log(android.isAndroid);      // boolean
console.log(android.isAndroidOld);   // Android < 4.4
console.log(android.isAndroidStock); // Stock Android browser

Capabilities Detection

Detect browser capabilities and features:

const caps = detector.detectCapabilities();

console.log(caps.hasTouch);      // Touch events support
console.log(caps.hasCanvas);     // Canvas API
console.log(caps.hasWebgl);      // WebGL support
console.log(caps.hasHistory);    // History API
console.log(caps.hasFullscreen); // Fullscreen API
console.log(caps.hasMouseMove);  // Mouse move events

const ratio = detector.detectPixelRatio();
console.log(ratio.pixelRatio);   // number (e.g., 2)
console.log(ratio.isRetina);     // boolean

Client Hints (Modern API)

Use the modern User-Agent Client Hints API:

const hints = await detector.detectClientHints();

if (hints.supported) {
    console.log(hints.data?.platform);        // "Windows"
    console.log(hints.data?.architecture);    // "x86"
    console.log(hints.data?.mobile);          // false
    console.log(hints.data?.platformVersion); // "10.0.0"
}

Complete API

Detector Interface

interface Detector {
    // Detection methods
    detectAll(): Readonly<DetectorResult>;
    detectIOS(): Readonly<IOSDetectionResult>;
    detectAndroid(): Readonly<AndroidDetectionResult>;
    detectDevice(): Readonly<DeviceDetectionResult>;
    detectIE(): Readonly<IEDetectionResult>;
    detectBrowser(): Readonly<BrowserDetectionResult>;
    detectCapabilities(): Readonly<CapabilityDetectionResult>;
    detectDOMFeatures(): Readonly<DOMFeatureDetectionResult>;
    detectPixelRatio(): Readonly<PixelRatioResult>;
    detectEngine(): Readonly<EngineDetectionResult>;
    detectCPU(): Readonly<CPUDetectionResult>;
    detectClientHints(): Promise<Readonly<ClientHintsResult>>;

    // Version comparison helpers
    isBrowserVersionGreaterThan(version: number | false, compare: number): boolean;
    isBrowserVersionGreaterThanOrEqual(version: number | false, compare: number): boolean;
    isBrowserVersionLessThan(version: number | false, compare: number): boolean;
    isBrowserVersionLessThanOrEqual(version: number | false, compare: number): boolean;
    isBrowserVersionEqual(version: number | false, compare: number): boolean;
    isBrowserVersionInRange(version: number | false, min: number, max: number): boolean;
}

Browser Detection Result

interface BrowserDetectionResult {
    isFirefox: boolean;
    isChrome: boolean;
    isSafari: boolean;
    isEdge: boolean;
    isOpera: boolean;
    webp: boolean;              // WebP format support
    chromeVersion: number | false;
    firefoxVersion: number | false;
    safariVersion: number | false;
    edgeVersion: number | false;
    operaVersion: number | false;
}

Tree-Shakeable Imports

For optimal bundle size, import only what you need:

// Import specific detection functions
import { detectBrowser } from "@adddog/trivial-user-agent-detector/browser-detection";
import { detectDevice } from "@adddog/trivial-user-agent-detector/device-detection";
import { detectCPU } from "@adddog/trivial-user-agent-detector/cpu-detection";

// Use with explicit parameters
const browser = detectBrowser(navigator.userAgent, window.chrome, navigator.vendor);
const device = detectDevice(navigator.userAgent, false, false);
const cpu = detectCPU(navigator.userAgent, navigator.platform);

Available Subpath Imports

  • @adddog/trivial-user-agent-detector/android-detection
  • @adddog/trivial-user-agent-detector/browser-detection
  • @adddog/trivial-user-agent-detector/capability-detection
  • @adddog/trivial-user-agent-detector/client-hints
  • @adddog/trivial-user-agent-detector/cpu-detection
  • @adddog/trivial-user-agent-detector/device-detection
  • @adddog/trivial-user-agent-detector/engine-detection
  • @adddog/trivial-user-agent-detector/ios-detection
  • @adddog/trivial-user-agent-detector/types

Real-World Examples

Feature Detection

const detector = createDetector();
const browser = detector.detectBrowser();

// Check if browser supports a modern API
if (browser.isChrome && detector.isBrowserVersionGreaterThanOrEqual(browser.chromeVersion, 100)) {
    // Use modern Chrome API
    useModernAPI();
} else {
    // Use polyfill
    usePolyfill();
}

Responsive Design

const device = detector.detectDevice();
const caps = detector.detectCapabilities();

if (device.isMobile && caps.hasTouch) {
    // Mobile touch interface
    enableTouchControls();
} else {
    // Desktop mouse interface
    enableMouseControls();
}

Browser-Specific Workarounds

const browser = detector.detectBrowser();
const engine = detector.detectEngine();

if (engine.engine === "WebKit" && browser.isSafari) {
    // Safari-specific CSS
    applySafariWorkaround();
}

if (browser.isEdge && detector.isBrowserVersionEqual(browser.edgeVersion, 18)) {
    // Legacy Edge bug workaround
    applyEdge18Fix();
}

Progressive Enhancement

const caps = detector.detectCapabilities();
const ratio = detector.detectPixelRatio();

if (caps.hasWebgl) {
    render3DGraphics();
} else if (caps.hasCanvas) {
    render2DGraphics();
} else {
    renderStaticImage();
}

if (ratio.isRetina) {
    loadHighResImages();
}

Performance Notes

  • Lazy Evaluation - Detection functions only run when you request them
  • Caching - Results are cached after first access
  • Immutability - All results are frozen (Object.freeze) for safety
  • Tree-Shaking - Use subpath imports to minimize bundle size
  • Zero Runtime Overhead - No classes, no inheritance, pure functions

TypeScript Support

Full TypeScript support with strict types:

import type {
    DetectorResult,
    BrowserDetectionResult,
    DeviceType,
    CPUArchitecture,
    RenderingEngine,
    BrowserVersion,
} from "@adddog/trivial-user-agent-detector";

const detector = createDetector();
const result: DetectorResult = detector.detectAll();

Browser Support

Works in all modern browsers and Node.js environments:

  • ✅ Chrome/Edge (Chromium)
  • ✅ Firefox
  • ✅ Safari (macOS/iOS)
  • ✅ Opera
  • ✅ Legacy Edge (EdgeHTML)
  • ✅ Internet Explorer 8-11
  • ✅ Node.js (server-side rendering)

Why This Library?

  • Type-Safe: Built with strict TypeScript, no any types
  • Functional: Pure functions, no classes, fully immutable
  • Modern: Supports latest APIs like Client Hints
  • Comprehensive: Detects browsers, devices, engines, CPUs, and more
  • Battle-Tested: 180+ unit tests covering edge cases
  • Zero Dependencies: No external packages required
  • Small Bundle: Tree-shakeable, import only what you need

License

MIT

Contributing

Issues and PRs welcome!