toolready. User-Agent Parser

User-Agent Parser

Break a User-Agent string into browser, OS, engine, and device.

Browser
—
Engine
—
OS
—
Device
—

What this does

Splits a User-Agent header into four fields — browser, engine, OS and device — using a compact set of regexes that run in the page. Paste a line out of an access log, or press Parse my own UA to see what your current browser is announcing. Nothing you paste is sent anywhere; there is no lookup service behind this.

Mozilla/5.0 (Linux; Android 13; SM-G991B) AppleWebKit/537.36
  (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36

Browser  Chrome 126.0.0.0      OS      Android 13
Engine   WebKit 537.36         Device  mobile · SM-G991B

How is the browser worked out?

In a deliberate order, because nearly every Chromium browser also claims to be Chrome. Edge (Edg/), Opera (OPR/), Firefox and Samsung Internet are all tested before the Chrome/ token, so Edge is reported as Edge rather than Chrome. Safari is matched from its Version/ token, and the iOS wrappers CriOS and FxiOS are labelled separately — on iOS those are Safari's engine wearing another badge.

Why does Chrome show WebKit as the engine?

Because that is literally what the string says. Chromium ships Blink but keeps the AppleWebKit/537.36 token for compatibility, and this parser reports the token it finds rather than second-guessing it. Firefox is the only browser here that reports Gecko, matched from its Gecko/… Firefox/… pair.

Why is the version 126.0.0.0 rather than 126.0.6478.127?

Chrome's user-agent reduction froze the minor, build and patch fields at zero, so the string only tells you the major version. Apple does something similar in reverse: desktop Safari has reported the same frozen macOS version for years, so a "macOS 10.15.7" reading means "some recent macOS", not Catalina. Windows has its own trap — Windows NT 10.0 is sent by both Windows 10 and Windows 11, which is why the OS field shows 10/11 instead of picking one.

What counts as a bot?

Eighteen patterns are checked before anything else, and a match short- circuits the rest of the parse — search crawlers (Googlebot, Bingbot, DuckDuckBot, YandexBot, Baiduspider, Applebot), SEO crawlers (AhrefsBot, SemrushBot), link unfurlers (Slackbot, Discordbot, Twitterbot, facebookexternalhit), AI crawlers (GPTBot, ClaudeBot) and plain clients like curl, wget and python-requests. Because the parse stops there, a bot shows its name as the browser and leaves engine and OS unknown. That is intentional: those fields would be fiction for a crawler.

Can I trust what it says?

Treat the result as a claim, not evidence. The header is set by the client and anyone can send whatever they like — scrapers routinely copy a real Chrome string. There is a structural limit too: browsers are moving detail out of the UA and into Client Hints headers such as Sec-CH-UA-Platform-Version, which never appear in the string you are pasting, so a parser can only ever see the reduced version. For feature decisions in your own code, test for the feature instead of matching on this.

Related: HTTP status codes and CIDR calculator for the rest of a log line, and URL decoder for the request path.