ua-parser-js
Detects browser, engine, OS, CPU, and device type from a User-Agent string or Client Hints, in browsers and Node.js.
Repository Health
Technical Analysis
UAParser.js is a dependency-free, ES5-friendly JavaScript library that parses raw User-Agent strings — and, on Client Hints-capable browsers, the newer Sec-CH-UA header set — into structured browser, rendering engine, operating system, CPU architecture, and device-type information. It runs unmodified in both browser and Node.js environments, ships as CommonJS and native ESM builds with hand-written TypeScript definitions, and has been maintained since 2012 with an actively updated detection database covering modern browsers, bots, AI crawlers, in-app browsers, and progressive web apps.
The v2.x line splits detection concerns into independently importable submodules — bot-detection, browser-detection, device-detection, extensions, and helpers — each exposed through its own package.json subpath export, so consumers can pull in only the detector they need. A shared IData interface (is(), toString(), withClientHints(), withFeatureCheck()) lets every returned result progressively upgrade a basic UA-string parse into a Client-Hints-backed one when the runtime supports it, and a useExtension() API lets callers add custom regex rules without forking the library.
What You Get
- A single UAParser() call or class instance that extracts browser, engine, OS, CPU, and device data from any User-Agent string or Client Hints header set
- Per-detector subpath imports (ua-parser-js/bot-detection, /browser-detection, /device-detection) so you only ship the parsing logic you actually use
- Dual CommonJS/ESM builds plus hand-written TypeScript .d.ts definitions for every submodule
- A useExtension() API for adding or overriding regex-based detection rules without forking the library
- An optional CLI (script/cli.js) for parsing UA strings from the command line
Common Use Cases
- Analytics pipelines segmenting traffic by browser, OS, and device type from server-side request logs
- Bot and AI-crawler detection for rate limiting, serving lightweight responses, or flagging suspicious traffic
- Responsive server-side rendering that adapts markup or feature flags based on detected device type (mobile/tablet/smarttv/wearable/XR)
- Client-side feature detection gated on browser/engine version rather than fragile user-agent string sniffing
Under The Hood
Architecture
The core src/main/ua-parser.js (~1,560 lines) is a single IIFE-wrapped, dependency-free module built around a declarative regex-matcher table evaluated by a generic mapper function against user-agent strings and Client Hints headers, producing plain-object results for browser/cpu/device/engine/os. Detection categories that used to live inline — bot-detection, browser-detection, device-detection — have been split into standalone sibling modules under src/{bot,browser,device}-detection/, each shipping its own .js/.mjs/.d.ts triad and exposed as an npm subpath export, so consumers import only the detectors they need instead of pulling in the full library. Extension and helper concerns are further isolated into src/extensions/ua-parser-extensions.js and src/helpers/ua-parser-helpers.js. The core UAParser class mainly orchestrates: it merges default and user-supplied extension regex maps, exposes getBrowser/getCPU/getDevice/getEngine/getOS/getResult accessors, and defers to a shared IData interface (is/toString/withClientHints/withFeatureCheck) implemented per returned object. Changes to the core regex-matching engine ripple into every downstream submodule.
Tech Stack
A dual-target (browser + Node.js) library with zero runtime dependencies besides three small first-party companion packages (detect-europe-js, is-standalone-pwa, ua-is-frozen). The exports map in package.json ships dual module formats — CommonJS .js and native ESM .mjs — plus per-submodule hand-written TypeScript .d.ts files, with no bundler required to consume either format. Internal build tooling is shell/Node build scripts (script/build-dist.sh, script/build-esm.js) plus uglify-js for minified dist bundles — no webpack or Rollup. Devtooling includes ESLint 9, JSHint (enforcing ES3/ES5 compatibility on the legacy core file), tsd for type-definition testing, lockfile-lint for supply-chain hygiene of package-lock.json, and @jazzer.js/core for fuzz-testing the regex engine. The project also ships a Docker image and a small bundled CLI (script/cli.js).
Code Quality
Tests are extensive and multi-layered: Mocha unit tests (test/unit/main.js, ua-ch.js, es6.mjs), dedicated spec files per submodule (test/unit/submodules/{helpers,extensions,browser-detection,device-detection,bot-detection}.spec.js), Playwright end-to-end browser tests (test/e2e), a ReDoS fuzz-testing harness via Jazzer.js (test/fuzz/redos.js), and CLI-specific tests. Coverage is measured with nyc. Linting runs both ESLint (modern JS in submodules) and JSHint (ES3/ES5 constraints on the legacy core), plus tsd for type-definition correctness and lockfile-lint for the lockfile. CI (ci-build-test.yml) is supplemented by separate CodeQL and dependency-review analysis workflows. Error handling in the core favors graceful degradation over throwing — malformed input yields undefined/empty fields rather than exceptions, an appropriate posture for a parser that must never crash on arbitrary request headers.
API Design
The public API stays ergonomic for a library maintained since 2012: instantiate new UAParser(uaString?) or call it as a function, then read getBrowser()/getDevice()/getOS()/etc., or getResult() for everything at once. Every returned object implements the same IData interface, and its async withClientHints()/withFeatureCheck() methods let callers progressively enhance a basic UA-string parse with User-Agent Client Hints when the runtime provides them — a distinguishing detail, since many competing UA parsers only read the static UA string. Subpath exports let consumers tree-shake down to a single detector (ua-parser-js/bot-detection) instead of the whole library, and useExtension() adds custom regex rules without forking. Zero configuration is required to get a first result.
Used by 30 apps in this directory
Cap
Team Chat · Video Conferencing
Open source Loom alternative with GPU-accelerated recording, instant share links, AI summaries, and full self-hosting via Docker Compose.
Chaskiq
CRM · Customer Support
Self-hosted live chat, video calls, help center, and marketing automation — a full-stack Intercom alternative you run on your own infrastructure.
Coder
Devops · Developer Tools · Code Editors
Self-hosted cloud development environments and AI coding agents — defined in Terraform, connected via WireGuard, automatically shut down when idle.
CodeSandbox
Code Editors · Developer Tools
Instantly ready browser-based IDE that runs full npm dependency resolution and transpilation entirely client-side, with no server needed.
Countly
Analytics · Marketing
Privacy-first, self-hosted analytics and customer engagement platform with full data ownership, GDPR compliance, and AI-powered insights across mobile, web, desktop, and IoT.
Documenso
Digital Signiture
Self-hosted, open-source DocuSign alternative with legally binding PDF signatures, multi-party workflows, and a full REST and tRPC API.
Element Web
Team Chat · Collaboration
A polished, self-hostable Matrix client for secure, decentralized messaging and collaboration that puts your organization in full control of its data.
ezBookkeeping
Invoicing Finance
Lightweight self-hosted personal finance manager with AI receipt scanning, multi-currency support, and MCP integration for complete data privacy.
Fern
Developer Tools
Fern turns a single OpenAPI, AsyncAPI, or Protobuf definition into type-safe SDKs for nine languages and a hosted API documentation site, all from one CLI and one source of truth.