TypeScript User-Agent Detection for Browser & Node.js – ua-parser-modern
navigator.brave.isBrave() in browser contexts to identify Brave, which deliberately spoofs Chrome.navigator.maxTouchPoints and navigator.standalone to separate iPadOS from macOS when both report the same UA string.1. Install ua-parser-modern using your preferred package manager.
# Yarn $ yarn add ua-parser-modern # NPM $ npm install ua-parser-modern # PNPM $ pnpm install ua-parser-modern
2. parseUA is the primary entry point. Pass a UA string directly, or call it with no argument in a browser context to read navigator.userAgent automatically.
import { parseUA } from 'ua-parser-modern'
// OR
import { parseUA } from 'https://esm.sh/ua-parser-modern';
// Parse the current browser's UA string (browser context, no argument needed)
const result = parseUA(navigator.userAgent)
// Browser information
console.log(result.browser)
// { name: 'Firefox', version: '125.0.0', major: '125' }
// Operating system
console.log(result.os)
// { name: 'Windows', version: '10' }
// Device (undefined type = desktop)
console.log(result.device)
// { model: 'iPad', type: 'tablet', vendor: 'Apple' }
// Rendering engine
console.log(result.engine)
// { name: 'Gecko', version: '125.0' }
// CPU architecture
console.log(result.cpu)
// { architecture: 'amd64' } 3. Each detection category has its own exported function. Import only the one you need.
import {
parseBrowser,
parseCPU,
parseDevice,
parseEngine,
parseOS,
} from 'ua-parser-modern'
const ua =
'Mozilla/5.0 (Linux; Android 14; Pixel 8 Pro) AppleWebKit/537.36 ' +
'(KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36'
// Returns { name: 'Chrome', version: '124.0.0.0', major: '124' }
const browser = parseBrowser(ua)
// Returns { architecture: 'arm64' }
const cpu = parseCPU(ua)
// Returns { model: 'Pixel 8 Pro', type: 'mobile', vendor: 'Google' }
const device = parseDevice(ua)
// Returns { name: 'Blink', version: '124.0.0.0' }
const engine = parseEngine(ua)
// Returns { name: 'Android', version: '14' }
const os = parseOS(ua) 4. Extend ua-parser-modern with custom Regex patterns:
The
extensionsobject accepts keys forbrowser,cpu,device,engine, andos. Each key’s value must be an array with an even number of entries: alternating regex arrays and property descriptor arrays.
import { BROWSER, parseUA } from 'ua-parser-modern'
// Define a custom browser rule set.
// Structure: [ [regex array], [property descriptor array] ]
// Each pair alternates: odd index = regex list, even index = property list.
const internalCrawlerRules = [
// Match "AcmeCrawler/2.1" in any UA string
[/(acmecrawler)/([w.]+)/i],
// Map capture group 1 -> name, capture group 2 -> version
[BROWSER.NAME, BROWSER.VERSION],
]
// Parse a proprietary crawler UA string with the custom browser extension
const result = parseUA('Mozilla/5.0 AcmeCrawler/2.1', {
browser: internalCrawlerRules,
})
console.log(result.browser)
// { name: 'AcmeCrawler', version: '2.1', major: '2' } parseUA(uastringOrExtensions?, extensions?)
Returns a lazy IResult object:
interface IResult {
ua: string
browser: { name?: string; version?: string; major?: string }
cpu: { architecture?: string }
device: { model?: string; type?: string; vendor?: string }
engine: { name?: string; version?: string }
os: { name?: string; version?: string }
} parseBrowser(uastringOrExtensions?, extensions?)
Returns IBrowser. Properties:
name (string | undefined): Browser name. Examples: 'Chrome', 'Firefox', 'Edge', 'Safari', 'Samsung Internet', 'Brave'.version (string | undefined): Full version string. Example: '124.0.0.0'.major (string | undefined): Major version as a string, extracted from version. Example: '124'.parseCPU(uastringOrExtensions?, extensions?)
Returns ICPU. Properties:
architecture (string | undefined): CPU architecture. Recognized values include 'amd64', 'ia32', 'arm64', 'armhf', 'arm', 'sparc', 'ppc', 'ia64', and others derived from the UA string.parseDevice(uastringOrExtensions?, extensions?)
Returns IDevice. Properties:
model (string | undefined): Device model name. Examples: 'iPhone', 'Pixel 8 Pro', 'iPad', 'Galaxy S23 Ultra'.type (string | undefined): Device category. One of 'mobile', 'tablet', 'console', 'smarttv', 'wearable', or 'embedded'. Returns undefined for desktop user agents — undefined type means desktop.vendor (string | undefined): Device manufacturer. Examples: 'Apple', 'Samsung', 'Google', 'Xiaomi'.parseEngine(uastringOrExtensions?, extensions?)
Returns IEngine. Properties:
name (string | undefined): Rendering engine name. Examples: 'Blink', 'Gecko', 'WebKit', 'Trident', 'EdgeHTML', 'Presto'.version (string | undefined): Engine version string.parseOS(uastringOrExtensions?, extensions?)
Returns IOS. Properties:
name (string | undefined): OS name. Examples: 'Windows', 'Android', 'iOS', 'Mac OS', 'Linux', 'ChromiumOS', 'HarmonyOS'.version (string | undefined): OS version string. Examples: '10', '14', '13.3.1'.Q: Can I use ua-parser-modern in a Node.js service to parse UA strings from HTTP request headers?
A: Yes. Pass the header value directly as a string to any named parser. parseBrowser(req.headers['user-agent']) works in any Node.js HTTP framework.
Q: The device.type property returns undefined for my desktop browser. Is that a bug?
A: No. The library treats undefined as the desktop signal. Check for 'mobile', 'tablet', 'console', 'smarttv', 'wearable', or 'embedded' to catch non-desktop contexts.
Q: My internal automation tool’s UA string is not recognized. How do I add it?
A: Use the extensions argument. Define a regex-property pair array, then pass it as the second argument to any parser or to parseUA. The BROWSER, DEVICE, and OS constants give you the correct string keys for property descriptors.
Q: Does the library handle very long UA strings sent by some crawlers?
A: The library trims any input to 500 characters before passing it to the regex engine. Standard browser and bot UA strings are well under this limit.
The post TypeScript User-Agent Detection for Browser & Node.js – ua-parser-modern appeared first on CSS Script.
The U.S. Capitol on March 3, 2026. (Photo by Jennifer Shutt/States Newsroom)WASHINGTON — U.S. Senate…
The new trailer for Dune: Part 3 just dropped and it looks incredible. The third…
Iran’s cyber operations took a sharp turn in early 2026, with state-linked threat actors quietly…
Karen Tilly is being recognized as a Remarkable Woman for her years of service and…
A plan to build 32 new housing units along Alpine Road in Rockford, IL, consisting…
Invincible is returning for its fourth season, which will finally pit Mark against one of…
This website uses cookies.