bowser vs platform vs ua-parser-js
浏览器 User-Agent 解析库技术选型
bowserplatformua-parser-js类似的npm包:

浏览器 User-Agent 解析库技术选型

bowserplatformua-parser-js 都是用于解析浏览器 User-Agent 字符串的 JavaScript 库,旨在帮助开发者识别用户的环境信息。bowser 专注于轻量级的浏览器版本检测,提供简洁的 API 来判断浏览器类型和版本。platform 是一个历史悠久的库,提供基本的操作系统和浏览器名称识别,但近年来维护频率较低。ua-parser-js 则是功能最全面的方案,支持解析浏览器、引擎、操作系统和设备详情,广泛用于需要精细环境识别的场景。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
bowser05,737258 kB914 个月前MIT
platform03,246-346 年前MIT
ua-parser-js010,1271.32 MB196 天前AGPL-3.0-or-later

Bowser vs Platform vs UAParser-js: 解析 User-Agent 的最佳实践

在前端架构中,准确识别用户环境是兼容性处理、数据分析和安全风控的基础。bowserplatformua-parser-js 是三个最常见的解决方案,但它们的設計理念和适用场景截然不同。本文将从核心 API、功能深度、安全性三个维度进行深度对比。

🛠️ 核心解析方式:实例化 vs 全局对象

三个库的入口方式不同,这直接影响代码的可维护性和测试难度。

bowser 采用函数式链式调用,无状态设计,适合按需解析。

import bowser from 'bowser';

const ua = navigator.userAgent;
const parser = bowser.getParser(ua);
const browser = parser.getBrowser();
// 输出:{ name: 'Chrome', version: '91.0' }

platform 通常暴露一个全局对象,在浏览器端自动解析,Node.js 端需手动调用。

import platform from 'platform';

// 浏览器环境自动填充
console.log(platform.name); 

// Node.js 环境需手动解析
const info = platform.parse(ua);
// 输出:{ name: 'Chrome', version: '91.0', os: ... }

ua-parser-js 采用类实例化模式,支持复用解析器实例,适合批量处理。

import UAParser from 'ua-parser-js';

const parser = new UAParser(ua);
const result = parser.getResult();
// 输出:{ browser: {...}, os: {...}, device: {...} }

🌐 浏览器版本判断:简洁 vs 繁琐

在做功能降级时,我们经常需要判断“浏览器是否大于某版本”。

bowser 提供了内置的 satisfies 方法,语义最清晰。

import bowser from 'bowser';

const isValid = bowser.getParser(ua).satisfies({
  chrome: ">=80",
  firefox: ">=75"
});
// 返回 true 或 false

platform 没有内置版本比较逻辑,需要手动解析版本号字符串。

import platform from 'platform';

const info = platform.parse(ua);
const version = parseFloat(info.version);
const isValid = info.name === 'Chrome' && version >= 80;
// 需要自行处理版本字符串比较逻辑

ua-parser-js 同样需要手动比较,但它提供的版本信息结构更标准化。

import UAParser from 'ua-parser-js';

const parser = new UAParser(ua);
const browser = parser.getBrowser();
const isValid = browser.name === 'Chrome' && parseFloat(browser.version) >= 80;
// 需自行编写比较逻辑

📱 设备与操作系统识别:深度对比

当需要区分 iOS 与 Android,或识别特定设备型号时,库的能力差异明显。

bowser 主要关注浏览器本身,操作系统信息较为基础。

import bowser from 'bowser';

const os = bowser.getParser(ua).getOS();
// 输出:{ name: 'iOS', version: '14.5' }
// 不提供具体设备型号(如 iPhone 12)

platform 提供基本的操作系统名称,但设备识别能力有限。

import platform from 'platform';

const info = platform.parse(ua);
console.log(info.os); 
// 输出:'iOS 14.5'
// 难以获取具体的设备硬件信息

ua-parser-js 提供独立的 device 对象,能识别厂商和型号。

import UAParser from 'ua-parser-js';

const parser = new UAParser(ua);
const device = parser.getDevice();
// 输出:{ vendor: 'Apple', model: 'iPhone', type: 'mobile' }

⚠️ 安全性与维护状态:关键决策点

在生产环境中,解析库的安全性至关重要,尤其是防止正则表达式拒绝服务攻击(ReDoS)。

bowser 代码库较小,正则逻辑相对简单,历史安全记录良好。

// bowser 内部维护正则表
// 社区响应速度快,Issue 修复及时

platform 曾曝出 CVE-2021-23358 安全漏洞,且近年来更新频率极低。

// 已知存在 ReDoS 风险
// 建议避免在新项目中使用,迁移成本较低

ua-parser-js 也曾受 CVE-2021-23358 影响,但已发布补丁并持续维护。

// 已修复已知漏洞
// 拥有活跃的维护团队和定期的安全更新

📊 核心特性对比表

特性bowserplatformua-parser-js
包体积⚡ 极小 (~5kb)🍃 小 (~10kb)📦 中等 (~20kb)
浏览器判断✅ 内置版本比较❌ 需手动比较❌ 需手动比较
设备型号识别❌ 不支持❌ 不支持✅ 支持厂商/型号
维护状态🟢 活跃🔴 停滞/低风险🟢 活跃
安全性🟢 高🟠 已知漏洞🟢 高(已修复)

💡 架构师建议

bowser 是轻量级首选 🪶。如果你的需求仅限于“判断浏览器版本”来决定是否加载 polyfill 或展示提示,它的 API 最友好,体积最小。

ua-parser-js 是全能型选手 🛡️。如果你需要构建用户画像、分析设备分布或进行精细化的兼容性控制,它提供的数据维度最丰富。

platform 应逐步淘汰 🗑️。鉴于其维护状态和安全历史,除非受限于遗留系统依赖,否则不应在新架构中引入。

最终建议:现代前端项目推荐优先使用 bowser 处理逻辑判断,配合 ua-parser-js 处理数据分析需求。避免使用 platform 以降低潜在的安全维护成本。

如何选择: bowser vs platform vs ua-parser-js

  • bowser:

    选择 bowser 如果你的主要需求是判断浏览器类型和版本(例如检查是否为 Chrome 80+),且希望包体积尽可能小。它的 API 设计直观,适合在现代前端项目中做简单的兼容性降级或功能开关。

  • platform:

    不建议在新项目中选择 platform。该库近年来维护活动较少,且历史上曾出现过安全漏洞(如 ReDoS 攻击风险)。除非你正在维护依赖它的旧系统,否则应优先考虑更活跃的替代方案。

  • ua-parser-js:

    选择 ua-parser-js 如果你需要获取详细的设备信息(如手机型号)、操作系统版本或渲染引擎详情。它是社区标准之一,更新频繁,适合需要高准确度解析复杂 User-Agent 字符串的企业级应用。

bowser的README

Bowser

A small, fast and rich-API browser/platform/engine detector for both browser and node.

  • Small. Use plain ES5-version which is ~4.8kB gzipped.
  • Optimized. Use only those parsers you need — it doesn't do useless work.
  • Multi-platform. It's browser- and node-ready, so you can use it in any environment.

Don't hesitate to support the project on Github or OpenCollective if you like it ❤️ Also, contributors are always welcome!

Financial Contributors on Open Collective Downloads

Contents

Overview

The library is made to help to detect what browser your user has and gives you a convenient API to filter the users somehow depending on their browsers. Check it out on this page: https://bowser-js.github.io/bowser-online/.

⚠️ Version 2.0 breaking changes ⚠️

Version 2.0 has drastically changed the API. All available methods are on the docs page.

For legacy code, check out the 1.x branch and install it through npm install bowser@1.9.4.

Use cases

First of all, require the library. This is a UMD Module, so it will work for AMD, TypeScript, ES6, and CommonJS module systems.

const Bowser = require("bowser"); // CommonJS

import * as Bowser from "bowser"; // TypeScript

import Bowser from "bowser"; // ES6 (and TypeScript with --esModuleInterop enabled)

By default, the exported version is the ES5 transpiled version, which do not include any polyfills.

In case you don't use your own babel-polyfill you may need to have pre-built bundle with all needed polyfills. So, for you it's suitable to require bowser like this: require('bowser/bundled'). As the result, you get a ES5 version of bowser with babel-polyfill bundled together.

You may need to use the source files, so they will be available in the package as well.

Browser props detection

Often we need to pick users' browser properties such as the name, the version, the rendering engine and so on. Here is an example how to do it with Bowser:

const browser = Bowser.getParser(window.navigator.userAgent);

console.log(`The current browser name is "${browser.getBrowserName()}"`);
// The current browser name is "Internet Explorer"

Using User-Agent Client Hints

Modern browsers support User-Agent Client Hints, which provide a more privacy-friendly and structured way to access browser information. Bowser can use Client Hints data to improve browser detection accuracy.

// Pass Client Hints as the second parameter
const browser = Bowser.getParser(
  window.navigator.userAgent,
  window.navigator.userAgentData
);

console.log(`The current browser name is "${browser.getBrowserName()}"`);
// More accurate detection using Client Hints

Working with Client Hints

Bowser provides methods to access and query Client Hints data:

const browser = Bowser.getParser(
  window.navigator.userAgent,
  window.navigator.userAgentData
);

// Get the full Client Hints object
const hints = browser.getHints();
// Returns the ClientHints object or null if not provided

// Check if a specific brand exists
if (browser.hasBrand('Google Chrome')) {
  console.log('This is Chrome!');
}

// Get the version of a specific brand
const chromeVersion = browser.getBrandVersion('Google Chrome');
console.log(`Chrome version: ${chromeVersion}`);

The Client Hints object structure:

{
  brands: [
    { brand: 'Google Chrome', version: '131' },
    { brand: 'Chromium', version: '131' },
    { brand: 'Not_A Brand', version: '24' }
  ],
  mobile: false,
  platform: 'Windows',
  platformVersion: '15.0.0',
  architecture: 'x86',
  model: '',
  wow64: false
}

Note: Client Hints improve detection for browsers like DuckDuckGo and other Chromium-based browsers that may have similar User-Agent strings. When Client Hints are not provided, Bowser falls back to standard User-Agent string parsing.

or

const browser = Bowser.getParser(window.navigator.userAgent);
console.log(browser.getBrowser());

// outputs
{
  name: "Internet Explorer"
  version: "11.0"
}

or

console.log(Bowser.parse(window.navigator.userAgent));

// outputs
{
  browser: {
    name: "Internet Explorer"
    version: "11.0"
  },
  os: {
    name: "Windows"
    version: "NT 6.3"
    versionName: "8.1"
  },
  platform: {
    type: "desktop"
  },
  engine: {
    name: "Trident"
    version: "7.0"
  }
}

You can also use Bowser.parse() with Client Hints:

console.log(Bowser.parse(window.navigator.userAgent, window.navigator.userAgentData));

// Same output structure, but with enhanced detection from Client Hints

Filtering browsers

You could want to filter some particular browsers to provide any special support for them or make any workarounds. It could look like this:

const browser = Bowser.getParser(window.navigator.userAgent);
const isValidBrowser = browser.satisfies({
  // declare browsers per OS
  windows: {
    "internet explorer": ">10",
  },
  macos: {
    safari: ">10.1"
  },

  // per platform (mobile, desktop or tablet)
  mobile: {
    safari: '>=9',
    'android browser': '>3.10'
  },

  // or in general
  chrome: "~20.1.1432",
  firefox: ">31",
  opera: ">=22",

  // also supports equality operator
  chrome: "=20.1.1432", // will match particular build only

  // and loose-equality operator
  chrome: "~20",        // will match any 20.* sub-version
  chrome: "~20.1"       // will match any 20.1.* sub-version (20.1.19 as well as 20.1.12.42-alpha.1)
});

Settings for any particular OS or platform has more priority and redefines settings of standalone browsers. Thus, you can define OS or platform specific rules and they will have more priority in the end.

More of API and possibilities you will find in the docs folder.

Browser names for .satisfies()

By default you are supposed to use the full browser name for .satisfies. But, there's a short way to define a browser using short aliases. The full list of aliases can be found in the file.

Similar Projects

  • Kong - A C# port of Bowser.

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

License

Licensed as MIT. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.