X Xerobit

User Agent String — What Browser User Agents Mean and How to Parse Them

A user agent string identifies the browser, OS, rendering engine, and version making an HTTP request. Here's how to read user agent strings and what each component means.

Mian Ali Khalid · · 6 min read
Use the tool
User Agent Parser
Parse any User-Agent string into browser, OS, device, and engine. Or detect your own. Built on the maintained ua-parser-js dataset.
Open User Agent Parser →

A user agent string is a text identifier sent in the HTTP User-Agent header by browsers and clients. It tells the server what software is making the request: the browser name and version, the operating system, and the rendering engine.

Use the User Agent Parser to decode any user agent string into structured data.

What a user agent string looks like

A typical Chrome browser on Windows:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36

An iPhone running Safari:

Mozilla/5.0 (iPhone; CPU iPhone OS 17_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Mobile/15E148 Safari/604.1

Firefox on Linux:

Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0

A bot (Googlebot):

Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

Why every browser says “Mozilla”

Every major browser starts with Mozilla/5.0 — even Chrome, Safari, and Edge. This is historical baggage from the browser wars of the 1990s.

The short history:

  1. Mosaic (1993) — first popular browser, no user agent standard
  2. Netscape Navigator — used Mozilla/1.0 as its identifier (“Mozilla” was Netscape’s internal name)
  3. Internet Explorer — to receive code intended for Netscape, IE started with Mozilla/2.0 (compatible; MSIE...)
  4. Modern browsers — Chrome, Safari, Firefox all inherited this pattern. All start with Mozilla/5.0 for maximum compatibility with servers that check for Mozilla.

The Mozilla/5.0 prefix is now meaningless as a browser identifier. The actual browser is identified by subsequent components.

Parsing the components

For Chrome on Windows:

Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
ComponentMeaning
Mozilla/5.0Legacy token — always present, ignore
(Windows NT 10.0; Win64; x64)OS: Windows 10, 64-bit
AppleWebKit/537.36Rendering engine: Blink (Chrome’s fork of WebKit)
(KHTML, like Gecko)Compatibility declaration
Chrome/124.0.0.0Actual browser: Chrome 124
Safari/537.36Compatibility token — Chrome identifies as Safari-compatible

For Safari on macOS:

Mozilla/5.0 (Macintosh; Intel Mac OS X 14_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15
ComponentMeaning
(Macintosh; Intel Mac OS X 14_4)OS: macOS 14.4
AppleWebKit/605.1.15Safari’s WebKit engine
Version/17.4.1Safari version
Safari/605.1.15Confirmation this is Safari

Windows NT version numbers

In user agents, Windows versions appear as NT numbers:

User AgentWindows Version
Windows NT 5.1Windows XP
Windows NT 6.1Windows 7
Windows NT 6.2Windows 8
Windows NT 6.3Windows 8.1
Windows NT 10.0Windows 10 and 11

Windows 10 and 11 both report Windows NT 10.0 — you can’t distinguish between them from the user agent alone.

macOS version in user agents

macOS versions in user agents use underscore-separated numbers:

User AgentmacOS Version
Mac OS X 10_15_7Catalina
Mac OS X 11_0Big Sur
Mac OS X 12_0Monterey
Mac OS X 13_0Ventura
Mac OS X 14_0Sonoma

Parsing user agents in code

JavaScript (ua-parser-js)

import UAParser from 'ua-parser-js';

const ua = new UAParser('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36');

const result = ua.getResult();
console.log(result.browser.name);    // "Chrome"
console.log(result.browser.version); // "124.0.0.0"
console.log(result.os.name);         // "Windows"
console.log(result.os.version);      // "10"
console.log(result.device.type);     // undefined (desktop)

Python (user-agents library)

from user_agents import parse

ua_string = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Mobile/15E148 Safari/604.1"
ua = parse(ua_string)

print(ua.browser.family)      # "Mobile Safari"
print(ua.browser.version_string) # "17.4.1"
print(ua.os.family)           # "iOS"
print(ua.os.version_string)   # "17.4.1"
print(ua.is_mobile)           # True
print(ua.device.family)       # "iPhone"

Node.js server-side detection

const UAParser = require('ua-parser-js');

app.use((req, res, next) => {
  const ua = new UAParser(req.headers['user-agent']);
  req.ua = ua.getResult();
  
  // Log mobile vs desktop:
  const isMobile = req.ua.device.type === 'mobile';
  console.log(`${isMobile ? 'Mobile' : 'Desktop'}: ${req.ua.browser.name} on ${req.ua.os.name}`);
  
  next();
});

Common bot user agents

Many user agents are automated bots, not humans:

Googlebot: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
Bingbot: "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)"
Twitterbot: "Twitterbot/1.0"
curl: "curl/8.4.0"
Python requests: "python-requests/2.31.0"
wget: "Wget/1.21.4"

Bots usually identify themselves clearly. User agents missing the Mozilla/5.0 prefix are typically CLI tools, bots, or testing tools.

The User-Agent Client Hints alternative

Modern Chrome-based browsers are moving to User-Agent Client Hints — a privacy-preserving alternative where the browser sends minimal UA data by default, and servers can request specific details:

// New header:
Sec-CH-UA: "Chromium";v="124", "Google Chrome";v="124"
Sec-CH-UA-Platform: "Windows"
Sec-CH-UA-Mobile: ?0

The old User-Agent string is being frozen (not updated with new versions) in Chrome. The practical impact: user agent version sniffing will become less reliable over time.


Related posts

Related tool

User Agent Parser

Parse any User-Agent string into browser, OS, device, and engine. Or detect your own. Built on the maintained ua-parser-js dataset.

Written by Mian Ali Khalid. Part of the Dev Productivity pillar.