bowser、detect-browser、platform、ua-parser-js、universal-user-agent、user-agent は、すべてブラウザや OS の情報を User-Agent 文字列から解析するための npm パッケージです。これらのライブラリは、クライアント環境の検出、機能フラグの判定、アナリティクス収集、条件付きレンダリングなどのユースケースで活用されます。ただし、パッケージごとに設計思想、API の使いやすさ、メンテナンス状況、対応環境が大きく異なります。ua-parser-js は最も包括的な解析機能を提供し、bowser はモダンな API と TypeScript サポートを重視しています。一方、platform と user-agent は長年使われてきた定番ライブラリですが、メンテナンス頻度に差があります。universal-user-agent は GitHub 環境での使用に特化しており、detect-browser はシンプルさを追求しています。
Web 開発において、ユーザーのブラウザ環境を正確に把握することは重要です。機能の互換性判定、アナリティクス収集、条件付きレンダリングなど、様々な場面で User-Agent 解析が必要になります。今回は 6 つの主要な npm パッケージを比較し、実際の開発現場でどのライブラリを選ぶべきか、技術的な観点から詳しく解説します。
各ライブラリがどの程度の情報を抽出できるかが最初の選定基準です。
ua-parser-js は最も包括的な解析機能を提供します。ブラウザ、OS、デバイス、エンジン、CPU まで詳細に解析可能です。
import { UAParser } from 'ua-parser-js';
const parser = new UAParser();
const result = parser.getResult();
console.log(result.browser); // { name: 'Chrome', version: '120.0.0.0' }
console.log(result.os); // { name: 'Windows', version: '11' }
console.log(result.device); // { type: 'desktop', vendor: undefined, model: undefined }
console.log(result.engine); // { name: 'Blink', version: '120.0.0.0' }
bowser も詳細な情報を提供しますが、API がよりモダンで使いやすい設計になっています。
import bowser from 'bowser';
const browser = bowser.getParser(window.navigator.userAgent);
console.log(browser.getBrowserName()); // 'Chrome'
console.log(browser.getBrowserVersion()); // '120.0.0.0'
console.log(browser.getOS()); // 'Windows'
console.log(browser.getPlatform()); // 'desktop'
detect-browser はブラウザ検出に特化しており、OS やデバイスの情報は提供しません。
import { detect } from 'detect-browser';
const browser = detect();
console.log(browser.name); // 'chrome'
console.log(browser.version); // '120.0.6099.109'
console.log(browser.os); // 'Windows 10' (限定的)
platform はブラウザと OS の基本情報を提供しますが、デバイス情報は限定的です。
import platform from 'platform';
console.log(platform.name); // 'Chrome'
console.log(platform.version); // '120.0.6099.109'
console.log(platform.os); // 'Windows 10'
console.log(platform.layout); // 'WebKit'
universal-user-agent は GitHub 環境に特化しており、一般 Web アプリケーション向けではありません。
import { getUserAgent } from 'universal-user-agent';
// Node.js 環境
const ua = getUserAgent();
// ブラウザ環境
const ua = getUserAgent(navigator);
user-agent は User-Agent 文字列の取得に特化しており、解析機能はほとんどありません。
import userAgent from 'user-agent';
// シンプルな文字列取得
const ua = userAgent();
実際の開発で最も使うのは、特定のブラウザかどうかを判定する機能です。
bowser はチェーン可能な判定メソッドを提供し、非常に読みやすいコードが書けます。
import bowser from 'bowser';
const browser = bowser.getParser(window.navigator.userAgent);
// バージョン範囲の判定
const isChrome = browser.satisfies({
chrome: '>115.0.0'
});
// 複合条件
const isModernBrowser = browser.satisfies({
chrome: '>100',
firefox: '>90',
safari: '>15',
edge: '>100'
});
// シンプルな判定
if (browser.is('mobile')) {
// モバイル向け処理
}
detect-browser はシンプルなオブジェクト返却のみで、判定ロジックは自分で実装する必要があります。
import { detect } from 'detect-browser';
const browser = detect();
// 自分で判定ロジックを書く
const isChrome = browser && browser.name === 'chrome';
const isModernChrome = browser &&
browser.name === 'chrome' &&
parseFloat(browser.version) >= 115;
ua-parser-js は結果オブジェクトから自分で判定条件を書きます。
import { UAParser } from 'ua-parser-js';
const parser = new UAParser();
const result = parser.getResult();
const isChrome = result.browser.name === 'Chrome';
const isVersion115Plus = parseFloat(result.browser.version) >= 115;
platform も同様に、自分で判定条件を実装します。
import platform from 'platform';
const isChrome = platform.name === 'Chrome';
const isWindows = platform.os.family === 'Windows';
モバイル、タブレット、デスクトップの判定はレスポンシブ設計で重要です。
bowser はデバイス判定メソッドを標準で提供しています。
import bowser from 'bowser';
const browser = bowser.getParser(window.navigator.userAgent);
if (browser.is('mobile')) {
// スマホ向け最適化
}
if (browser.is('tablet')) {
// タブレット向けレイアウト
}
if (browser.is('desktop')) {
// デスクトップ向け機能
}
// 組み合わせも可能
if (browser.is('mobile') && browser.is('android')) {
// Android スマホ向け処理
}
ua-parser-js は device.type で判定します。
import { UAParser } from 'ua-parser-js';
const parser = new UAParser();
const result = parser.getResult();
if (result.device.type === 'mobile') {
// スマホ向け
}
if (result.device.type === 'tablet') {
// タブレット向け
}
if (result.device.type === 'desktop') {
// デスクトップ向け
}
detect-browser はデバイス判定機能を提供していません。自分で実装するか、他のライブラリとの併用が必要です。
import { detect } from 'detect-browser';
const browser = detect();
// デバイス判定は別途実装が必要
const isMobile = /mobile/i.test(window.navigator.userAgent);
platform は限定的なデバイス情報を提供します。
import platform from 'platform';
// device プロパティは限定的
if (platform.product && /mobile/i.test(platform.product)) {
// モバイル判定
}
現代のフロントエンド開発では TypeScript が標準です。型定義の品質も重要な選定基準になります。
bowser はバージョン 2 以降、TypeScript 定義を公式に提供しており、型推論が良く効きます。
import bowser from 'bowser';
const browser = bowser.getParser(window.navigator.userAgent);
// 型が正しく推論される
const browserName: string = browser.getBrowserName();
const version: string = browser.getBrowserVersion();
// 判定結果も boolean 型
const isMobile: boolean = browser.is('mobile');
ua-parser-js も TypeScript 定義を提供していますが、やや複雑な型構造になります。
import { UAParser } from 'ua-parser-js';
const parser = new UAParser();
const result = parser.getResult();
// 結果の型は IResult
const browserName: string | undefined = result.browser.name;
const osName: string | undefined = result.os.name;
detect-browser は TypeScript 定義を提供していますが、型はシンプルです。
import { detect } from 'detect-browser';
const browser = detect();
// null 返却の可能性を考慮する必要がある
if (browser) {
const name: string = browser.name;
const version: string = browser.version;
}
platform の TypeScript サポートはコミュニティ維持の型定義に依存しており、公式サポートではありません。
import platform from 'platform';
// @types/platform を別途インストールする必要あり
const name: string = platform.name;
サーバーサイドレンダリング(SSR)や Node.js 環境での使用も考慮する必要があります。
ua-parser-js はブラウザと Node.js の両方で完全に動作します。
// ブラウザ環境
import { UAParser } from 'ua-parser-js';
const parser = new UAParser();
// Node.js 環境で User-Agent 文字列を指定
const parser = new UAParser(req.headers['user-agent']);
const result = parser.getResult();
bowser も両環境に対応しています。
// ブラウザ
import bowser from 'bowser';
const browser = bowser.getParser(window.navigator.userAgent);
// Node.js
const browser = bowser.getParser(req.headers['user-agent']);
detect-browser は主にブラウザ向けですが、Node.js でも動作します。
import { detect } from 'detect-browser';
// ブラウザ
const browser = detect();
// Node.js では navigator が必要
const browser = detect(navigator.userAgent);
platform は両環境対応ですが、Node.js では限定的な情報しか取得できません。
import platform from 'platform';
// Node.js では navigator がないため限定的
const name = platform.name;
universal-user-agent は名前の通り、両環境での User-Agent 取得に特化しています。
import { getUserAgent } from 'universal-user-agent';
// 環境を自動検出
const ua = getUserAgent();
// ブラウザで明示的に指定
const ua = getUserAgent(navigator);
パッケージのメンテナンス状況は長期的なプロジェクトにとって重要です。
platform は更新頻度が非常に低く、新規プロジェクトでの採用は慎重に検討すべきです。既存プロジェクトで使用されている場合は、ua-parser-js または bowser への移行を検討してください。
user-agent パッケージも機能が限定的で、更新が停滞しています。新規プロジェクトでの使用は推奨されません。
universal-user-agent は GitHub 関連ツールに特化しており、一般 Web アプリケーションでは他のライブラリを選ぶべきです。
bowser と ua-parser-js は活発にメンテナンスされており、新規プロジェクトでの採用に最も適しています。
detect-browser はシンプルさを重視するプロジェクトで、更新は継続されていますが機能追加は限定的です。
推奨:bowser
型安全性、モダンな API、包括的な機能が必要な場合に最適です。
import bowser from 'bowser';
class EnvironmentDetector {
constructor(userAgent) {
this.parser = bowser.getParser(userAgent);
}
shouldEnableFeature(featureName) {
const rules = {
'advancedAnimation': {
chrome: '>115',
firefox: '>110',
safari: '>16'
},
'webGL': {
chrome: '>100',
firefox: '>90'
}
};
return this.parser.satisfies(rules[featureName]);
}
getOptimizedLayout() {
if (this.parser.is('mobile')) {
return 'mobile';
} else if (this.parser.is('tablet')) {
return 'tablet';
}
return 'desktop';
}
}
推奨:ua-parser-js
詳細な環境情報を収集する必要がある場合に最適です。
import { UAParser } from 'ua-parser-js';
function collectAnalytics() {
const parser = new UAParser();
const result = parser.getResult();
const analyticsData = {
browser: result.browser.name,
browserVersion: result.browser.version,
os: result.os.name,
osVersion: result.os.version,
deviceType: result.device.type,
engine: result.engine.name
};
// 送信処理
sendToAnalytics(analyticsData);
}
推奨:detect-browser
バンドルサイズを最小限に抑えたい場合に適しています。
import { detect } from 'detect-browser';
function isSupportedBrowser() {
const browser = detect();
if (!browser) return false;
const supported = [
{ name: 'chrome', minVersion: 100 },
{ name: 'firefox', minVersion: 90 },
{ name: 'safari', minVersion: 15 }
];
return supported.some(s =>
browser.name === s.name &&
parseFloat(browser.version) >= s.minVersion
);
}
推奨:ua-parser-js または bowser
両方とも Node.js 環境で User-Agent 文字列を指定して解析できます。
// Next.js の getServerSideProps 例
import { UAParser } from 'ua-parser-js';
export async function getServerSideProps({ req }) {
const parser = new UAParser(req.headers['user-agent']);
const result = parser.getResult();
return {
props: {
isMobile: result.device.type === 'mobile',
browserName: result.browser.name
}
};
}
| 機能 | bowser | detect-browser | platform | ua-parser-js | universal-user-agent | user-agent |
|---|---|---|---|---|---|---|
| ブラウザ名取得 | ✅ | ✅ | ✅ | ✅ | ⚠️ | ⚠️ |
| ブラウザバージョン | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
| OS 情報 | ✅ | ⚠️ 限定的 | ✅ | ✅ | ❌ | ❌ |
| デバイスタイプ | ✅ | ❌ | ⚠️ 限定的 | ✅ | ❌ | ❌ |
| エンジン情報 | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ |
| TypeScript 対応 | ✅ 公式 | ✅ | ⚠️ コミュニティ | ✅ | ✅ | ⚠️ |
| Node.js 対応 | ✅ | ⚠️ | ✅ | ✅ | ✅ | ✅ |
| バージョン判定 | ✅ satisfies | ❌ 手動 | ❌ 手動 | ❌ 手動 | ❌ | ❌ |
| メンテナンス状況 | ✅ 活発 | ✅ 継続 | ⚠️ 低調 | ✅ 活発 | ✅ 特定用途 | ⚠️ 低調 |
新規プロジェクトでの優先順位:
bowser — モダンな API、TypeScript サポート、包括的な機能。大規模プロジェクトに最適。ua-parser-js — 最も詳細な解析情報。アナリティクスやきめ細かい環境判定が必要な場合に最適。detect-browser — シンプルさ重視。バンドルサイズを最小限に抑えたい場合に選択。避けるべきパッケージ:
platform — 更新頻度が低く、新規プロジェクトでの採用は非推奨。user-agent — 機能が限定的で、他のライブラリで十分カバー可能。universal-user-agent — GitHub 関連ツール以外での使用は不適切。User-Agent 文字列自体がプライバシー強化のため変更される動きがあります(User-Agent Client Hints)。長期的なプロジェクトでは、Client Hints API との併用も検討すべきです。
// User-Agent Client Hints の例
if (navigator.userAgentData) {
const hints = await navigator.userAgentData.getHighEntropyValues([
'platform',
'platformVersion',
'architecture',
'model',
'uaFullVersion'
]);
console.log(hints);
}
現在のところは、従来の User-Agent 解析ライブラリと Client Hints を組み合わせるのが最も堅牢なアプローチです。bowser と ua-parser-js はこの移行期間においても信頼できる選択肢と言えます。
bowser を選ぶべきなのは、モダンな TypeScript プロジェクトで型安全性を重視する場合です。ES6 モジュール対応が良く、ブラウザと Node.js の両方で動作します。バージョン 2 以降は User-Agent 文字列の直接指定もサポートしており、テストがしやすい設計になっています。大規模アプリケーションや、ブラウザバージョンに基づく機能制御が必要なプロジェクトに適しています。
detect-browser は最小限の依存とシンプルな API を求める場合に最適です。ブラウザ検出に特化しており、OS やデバイスの詳細情報までは不要というユースケースに向いています。バンドルサイズを気にするプロジェクトや、単純なブラウザ判定だけが必要な場合に選択しましょう。ただし、機能は他のライブラリに比べて限定的です。
platform は長年の実績があるライブラリですが、更新頻度が低いため新規プロジェクトでの採用は慎重に検討してください。既存プロジェクトで既に使用されている場合は継続利用も現実的ですが、新規導入なら ua-parser-js や bowser の方がメンテナンス面で安心です。シンプルな環境検出が必要なレガシーシステムとの互換性を重視する場合に検討します。
ua-parser-js を選ぶべきなのは、最も詳細な環境情報が必要な場合です。ブラウザ、OS、デバイス、エンジン、CPU まで解析可能で、サーバーサイドとクライアントサイドの両方で動作します。アナリティクス収集や、きめ細かい環境判定が必要なプロジェクトに最適です。コミュニティも活発で、長期的なメンテナンスが期待できます。
universal-user-agent は GitHub 関連のツールや、GitHub Actions 環境での使用に特化しています。一般の Web アプリケーションでは他のライブラリを検討すべきです。GitHub API クライアントを構築する場合や、GitHub 環境でのユーザーエージェント統一が必要な場合にのみ選択してください。
user-agent パッケージは機能が限定的で、更新も停滞気味です。新規プロジェクトでの採用は推奨されません。既存プロジェクトで使用中の場合は、ua-parser-js または bowser への移行を検討すべきです。シンプルな User-Agent 文字列の取得のみが必要な最小限のユースケース以外では、他の選択肢の方が良いでしょう。
A small, fast and rich-API browser/platform/engine detector for both browser and node.
Don't hesitate to support the project on Github or OpenCollective if you like it ❤️ Also, contributors are always welcome!
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 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.
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.
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"
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
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
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.
.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.
This project exists thanks to all the people who contribute. [Contribute].
Become a financial contributor and help us sustain our community. [Contribute]
Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]
Licensed as MIT. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details.