Skip to main content

User Agent Parser

Parse user agent strings to identify browser, OS and device.

Reviewed by · Last reviewed

Using the User Agent Parser

  1. Paste a user agent string into the input - your current browser\'s UA is pre-populated as a starting example. Any UA string (desktop, mobile, bot, IoT device) works.
  2. Click "Parse" - the tool runs a regex-based detection cascade that extracts browser name and version, OS name and version, device type (desktop, mobile, tablet), and rendering engine (Blink, Gecko, WebKit, Trident, Presto).
  3. Read the breakdown - each detected field appears with the matched substring, so you can see why the parser reached its conclusion (useful when detection looks wrong).
  4. Inspect the raw tokens - the parser also shows the UA string tokenized on semicolons and parentheses, letting you spot vendor-specific additions (product tokens, OEM identifiers, custom app wrappers).
  5. Copy the normalized result - the output can be copied as JSON for pasting into bug reports, analytics queries, or documentation.

How UA Parsing Works

The User-Agent header is a plain-text product identifier string, defined in RFC 9110 (HTTP Semantics, section 10.1.5) as "a sequence of product tokens identifying the user agent software and any significant subproducts." In practice, the format is a horror story of backward compatibility: every modern browser claims to be Mozilla/5.0, includes fake tokens identifying Safari/KHTML/Gecko to pass sniffing checks on ancient sites, and appends its actual identifier late in the string. Parsing correctly requires a cascade of regex tests in specific precedence order.

This parser runs ordered rules: check for bots first (Googlebot, Bingbot, Slackbot, dozens of crawlers) since their strings are more deterministic; then check Edge and Opera before Chrome (because their UAs contain "Chrome"); then check Chrome, Firefox, Safari, IE in that order. OS detection follows a similar cascade, with iPadOS special-cased because modern iPads masquerade as macOS by default. Rendering engine is derived from the detected browser rather than parsed separately. The whole cascade runs in under a millisecond on any modern device.

When You Actually Need to Parse UA

  • Debugging server logs where one customer sees a broken page - parsing their UA reveals the exact browser and version to reproduce against.
  • Analytics queries in Search Console, PostHog, or Google Analytics where you need to break traffic down by browser family or device type.
  • Bot detection - identifying search-engine crawlers (Googlebot, Bingbot) for SEO audits, distinguishing legitimate bots from abusive scrapers by verifying reverse DNS.
  • Compatibility testing - feeding real-world UA strings from your traffic into BrowserStack or similar services to match test coverage to actual user distribution.
  • Researching how a specific application (Outlook, Slack desktop, Electron apps) identifies itself when embedding web content.

UA Parsing Edge Cases

  • iPad pretending to be macOS - since iPadOS 13, Safari on iPad sends a macOS UA by default. The only reliable iPad detection is navigator.maxTouchPoints > 1 on the client side; server-side you cannot distinguish an iPad from a MacBook by UA alone.
  • Chrome\'s UA freeze (User-Agent Reduction) - since Chrome 101 (2022), Google began reducing UA granularity, freezing minor version numbers and rounding OS versions. Fine-grained version detection on Chromium now requires User-Agent Client Hints instead.
  • Privacy-focused browsers - Brave, Tor Browser, and DuckDuckGo deliberately send generic UAs to reduce fingerprinting. Identifying them via UA alone is unreliable by design.
  • WebViews inside mobile apps - Facebook Messenger, Instagram, and TikTok in-app browsers append identifiers like FBAN/FBIOS, Instagram, or musical_ly. These are non-standard but parseable.
  • Spoofed UAs - developer tools in every browser allow UA spoofing, and command-line tools (curl -A) send arbitrary strings. Treat UA as an untrusted hint, never as a security boundary.
  • Bot fleets impersonating real browsers - sophisticated scrapers send realistic Chrome UAs. UA alone cannot distinguish a real user from a Playwright-automated Chrome instance; additional signals (TLS fingerprint, HTTP header order, behavioural patterns) are required.

The User-Agent Header and Its Replacement

RFC 9110 formalizes the UA header\'s syntax, but the content evolved by market pressure over 30 years of browser wars. Every browser claims Mozilla/5.0 to pass 1990s Netscape sniffing; every WebKit-based browser claims KHTML heritage; every Chromium-based browser claims Safari compatibility; Edge claims Chrome. The result is a string that lies about almost everything except its actual product token, because removing any claim breaks some old script somewhere on the web.

The replacement is User-Agent Client Hints (UA-CH), a W3C Editor\'s Draft deployed in Chromium since 2020. Instead of one monolithic string, UA-CH uses per-request headers like Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Platform, and Sec-CH-UA-Full-Version-List (sent only when requested via Accept-CH). Firefox and Safari have not adopted UA-CH yet; they continue relying on the traditional header.

Alternatives and Library Choices

For server-side parsing, ua-parser-js (MIT-licensed, 11M weekly downloads) is the de facto JavaScript standard. For Python, ua-parser wraps the community-maintained uap-core regex list. For bot detection, isbot focuses on crawlers. This parser uses a reduced rule set optimized for browsers you actually see in 2026 traffic; for exhaustive historical coverage, ua-parser-js is more thorough. For threat detection (scrapers, credential stuffers), UA parsing alone is insufficient - combine with TLS fingerprinting (JA3/JA4) and behavioural analysis.

Frequently Asked Questions

Can I trust what the User-Agent says?

No. The UA header is set by the client and can be arbitrary. Every browser's DevTools includes a UA-spoofing toggle, <code>curl -A</code> accepts any string, and automated traffic routinely impersonates Chrome. UA is a useful hint for analytics and progressive enhancement; it is never a security control. Use it for content negotiation (serving mobile layouts) and aggregate analytics; do not use it for authorization, abuse prevention, or feature gating that affects security.

Why does Chrome's UA look like it's pretending to be everything?

Historical backward compatibility. In the 1990s, sites sniffed for "Mozilla" to serve modern HTML. IE prefixed "Mozilla/4.0 (compatible; MSIE...)" to pass. Safari claimed KHTML and Gecko. Chrome claimed Safari. Edge claimed Chrome. Removing any claim would break some 25-year-old script somewhere on the web.

What is User-Agent Client Hints?

UA-CH is a W3C-track replacement for the UA header, shipping in Chromium. It splits the UA into headers (<code>Sec-CH-UA</code>, <code>Sec-CH-UA-Mobile</code>, <code>Sec-CH-UA-Platform</code>) that servers request via <code>Accept-CH</code>. High-entropy data is only sent when explicitly asked. Chrome, Edge, and Opera implement UA-CH; Firefox and Safari do not.

How do I distinguish iPad from Mac by UA?

You cannot, reliably. Since iPadOS 13 (2019), Safari on iPad sends a macOS user agent by default to behave more like "desktop Safari." The workarounds are client-side: check <code>navigator.maxTouchPoints</code> (iPads have >1, Macs have 0), check <code>navigator.platform</code>, or check for specific iPadOS-only APIs. Server-side, iPad and macOS traffic is indistinguishable from the UA alone; use Accept-CH to request the <code>Sec-CH-UA-Platform</code> hint if iPadOS is in scope (still experimental for iPads specifically).</p>

What is the difference between Blink, WebKit, and Gecko?

Three browser rendering engines with different lineages. WebKit was forked by Apple from KHTML (KDE's engine) in 2001 and powers Safari. Blink was forked from WebKit by Google in 2013 and now powers Chrome, Edge, Opera, Brave, Samsung Internet, and all Chromium-based browsers. Gecko was built from scratch by Mozilla starting in 1997 and powers Firefox. The legacy Trident (IE) and EdgeHTML (old Edge) engines are extinct except in edge enterprise deployments.

How accurate is version detection?

Browser version detection is accurate to the major version for Chrome, Firefox, Edge, and Safari, which all include their version number unmistakably in the UA. Minor version accuracy has degraded on Chromium since Chrome 101's User-Agent Reduction project, which freezes minor version numbers at a static value for privacy. For exact version data on modern Chromium, use UA-CH's <code>Sec-CH-UA-Full-Version-List</code>.

Can I detect Googlebot reliably?

Partially. Googlebot's UA includes a clearly identifying "Googlebot" token. But UAs can be spoofed, so real detection requires reverse DNS verification: resolve the IP to <code>*.googlebot.com</code> or <code>*.google.com</code>, then forward-lookup back to the IP. Google documents this at <code>developers.google.com/search/docs/crawling-indexing/verifying-googlebot</code>.

Why would a mobile app include UA parsing?

In-app browsers (Instagram webview, Facebook Messenger, Slack desktop) need to identify themselves so the web content they load can adapt. The webview vendor appends tokens like <code>FBAN/FBIOS</code>, <code>Instagram 280.0</code>, or <code>Slack/4.29.149</code> to the UA. Web content detects these to avoid features that break in webview (for example, the OAuth flow often needs to be opened in the external browser, not the in-app one).

Does the parser send my UA to a server?

No. Parsing is a pure function of regex matches against the input string. The Preact component accepts your UA, runs regex tests, and renders the result - no HTTP request is issued. You can paste an internal corporate app's UA without worrying about it leaking to any third party.

What should I use if I need every historical UA covered?

The community-maintained <code>ua-parser-js</code> library on npm is the most comprehensive open-source option, with regularly updated regex rules covering thousands of browsers, OSes, and devices including long-discontinued ones. For Python, the <code>ua-parser</code> package uses the same underlying uap-core regex database. This tool optimizes for browsers and crawlers you actually see today in 2026 traffic; for exhaustive historical coverage, use a library.

What about UA parsing in SSR or edge runtimes?

Regex-based parsing works identically in Node.js, Deno, Cloudflare Workers, Vercel Edge, and Bun. For SSR frameworks, parse the incoming <code>User-Agent</code> header server-side to pre-render device-specific layouts and avoid hydration shift.

Is UA parsing still worth learning?

Yes, with shrinking scope. UA-CH and traditional UA coexist for now - Chromium sends both, Firefox and Safari only UA. New systems should accept either, and popular libraries handle both. Treat UA parsing as a stable skill with gradually improving alternatives.

More Developer Tools