express-useragent、react-device-detect、ua-parser-js は、すべてクライアントの環境(ブラウザ、OS、デバイス種類)を特定するためのツールですが、役割と統合方法が異なります。ua-parser-js はフレームワークに依存しない軽量な解析ライブラリで、Node.js からブラウザまで幅広く動作します。express-useragent は Express アプリケーション専用のミドルウェアであり、リクエストオブジェクトに解析結果を付与します。react-device-detect は React 専用のコンポーネントとフックを提供し、デバイス種類に基づいた条件付きレンダリングを容易にします。
Web 開発において、クライアントがどのようなデバイスやブラウザを使用しているかを把握することは、レスポンシブデザインの最適化、機能のフラグ管理、セキュリティ対策などで重要です。express-useragent、react-device-detect、ua-parser-js はこの課題に取り組む代表的なパッケージですが、それぞれアーキテクチャと適用範囲が異なります。
本稿では、これら 3 つのパッケージを技術的な観点から比較し、プロジェクトの要件に合った選択ができるよう解説します。
これら 3 つのライブラリは、アプリケーションスタックの異なる層で動作するように設計されています。
ua-parser-js は純粋な JavaScript ライブラリです。
// ua-parser-js: 汎用的な解析
import UAParser from 'ua-parser-js';
const parser = new UAParser(userAgentString);
const result = parser.getResult();
console.log(result.browser.name); // "Chrome"
console.log(result.os.name); // "Windows"
express-useragent は Express 専用のミドルウェアです。
req.useragent を使用可能にします。// express-useragent: Express ミドルウェア
import express from 'express';
import expressUserAgent from 'express-useragent';
const app = express();
app.use(expressUserAgent.express());
app.get('/', (req, res) => {
// req.useragent に解析結果が付与される
if (req.useragent.isMobile) {
res.send('Mobile View');
}
});
react-device-detect は React 専用の UI ライブラリです。
// react-device-detect: React コンポーネント
import { BrowserView, MobileView } from 'react-device-detect';
function App() {
return (
<div>
<BrowserView>
<h1>Desktop Only Content</h1>
</BrowserView>
<MobileView>
<h1>Mobile Only Content</h1>
</MobileView>
</div>
);
}
デバイス検出の精度は、プロジェクトの信頼性に直結します。各パッケージが提供する情報の深さを比較します。
ua-parser-js は最も詳細な情報を提供します。
// ua-parser-js: 詳細な情報取得
const parser = new UAParser(ua);
const device = parser.getDevice();
console.log(device.vendor); // "Apple"
console.log(device.model); // "iPhone"
console.log(device.type); // "mobile"
express-useragent は主要なフラグに焦点を当てています。
isMobile、isDesktop、isTablet などのブーリアン値が手軽に使えます。// express-useragent: 簡易フラグ
app.get('/check', (req, res) => {
const ua = req.useragent;
res.json({
isMobile: ua.isMobile,
isDesktop: ua.isDesktop,
browser: ua.browser // ブラウザ名も取得可能
});
});
react-device-detect は表示制御に特化した情報を提供します。
// react-device-detect: 特定のブラウザ検出
import { IEView, SafariView } from 'react-device-detect';
function BrowserSpecific() {
return (
<>
<IEView>Only for Internet Explorer</IEView>
<SafariView>Only for Safari</SafariView>
</>
);
}
サーバーサイドレンダリング(SSR)を採用している場合、サーバーとクライアントでユーザーエージェントの取得方法が異なるため、不整合が起きるリスクがあります。
ua-parser-js はサーバー・クライアント両方で同じロジックを使えます。
// ua-parser-js: SSR での手動制御
// Server Side
const ua = req.headers['user-agent'];
const device = new UAParser(ua).getDevice();
// Client Side (useEffect etc.)
const device = new UAParser(navigator.userAgent).getDevice();
express-useragent はサーバーサイド専用です。
// express-useragent: サーバー限定
// クライアントサイドでは req オブジェクトがないため使用不可
// SSR 時には有効だが、クライアント側での再判定には別の手段が必要
react-device-detect はハイドレーションエラーに注意が必要です。
user-agent 文字列が異なる場合があり、レンダリング結果が一致しないことがあります。ssr プロパスを適切に設定するか、useEffect でマウント後に判定するなどの対策が必要です。// react-device-detect: SSR 対策
import { isMobile } from 'react-device-detect';
function Component() {
// SSR 時に false を返し、クライアントで再判定させるなどの工夫が必要
// または ssr プロパスを使用してサーバー側での挙動を制御
return <div>{isMobile ? 'Mobile' : 'Desktop'}</div>;
}
ライブラリの長期的な安定性は、アーキテクチャ決定において重要です。
ua-parser-js は業界標準に近い存在です。
express-useragent はメンテナンスが緩やかです。
react-device-detect は React コミュニティで支持されています。
| 特徴 | ua-parser-js | express-useragent | react-device-detect |
|---|---|---|---|
| 主な用途 | 汎用的な UA 解析 | Express ミドルウェア | React UI 条件付きレンダリング |
| 動作環境 | Node.js, ブラウザ | Node.js (Express) | React (Client/SSR) |
| 情報の詳細さ | ⭐⭐⭐ (非常に詳細) | ⭐⭐ (主要フラグ中心) | ⭐⭐ (表示制御中心) |
| フレームワーク依存 | なし | Express | React |
| SSR 対応 | 手動制御可能 | サーバー側のみ | 対応(注意必要) |
| メンテナンス状況 | 活発 | 緩やか | 活発 |
プロジェクトのアーキテクチャに応じて、以下のように選択することを推奨します。
ua-parser-js を選択してください。最も汎用性が高く、Express や React などのフレームワークに依存しないため、将来的な技術スタックの変更にも柔軟に対応できます。express-useragent は既存の Express プロジェクトで手軽に導入できますが、新規プロジェクトでは ua-parser-js をミドルウェアとしてラップする方が長期的な保守性が高まります。react-device-detect は、デバイスに応じた UI 切り替えを宣言的に行いたい React プロジェクトに最適です。ただし、SSR 環境ではハイドレーションの不整合に十分注意して実装してください。最終的なアドバイス: 可能な限り、デバイス検出ロジックを UI コンポーネントから分離し、ua-parser-js のような純粋なライブラリを使用してカスタムフックやコンテキストに統合することをお勧めします。これにより、テスト容易性が向上し、React や Express への依存を減らすことができます。
Express を使用したレガシーなサーバーサイドプロジェクトで、リクエストオブジェクト(req)に直接ユーザーエージェント情報を付与したい場合に選択します。ただし、メンテナンス頻度が他のライブラリに比べて低いため、新規プロジェクトでは ua-parser-js をミドルウェアとして組み込むことを検討してください。
React アプリケーションで、デバイス種類(モバイル、タブレット、デスクトップ)に応じて UI コンポーネントを切り替える必要がある場合に最適です。サーバーサイドレンダリング(SSR)環境では、ハイドレーションの不整合に注意して使用する必要があります。
フレームワークに依存せず、Node.js、ブラウザ、ビルドツールなど、あらゆる環境でユーザーエージェント文字列を詳細に解析したい場合に選択します。最も汎用性が高く、メンテナンスも活発なため、基盤となる解析エンジンとして推奨されます。
Fast user-agent parser with first-class Express middleware and TypeScript typings. Works server-side in Node.js and in the browser via a lightweight IIFE bundle.
Requires Node.js 18 or newer.
npm install express-useragent
import http from 'node:http';
import { UserAgent } from 'express-useragent';
const server = http.createServer((req, res) => {
const source = req.headers['user-agent'] ?? 'unknown';
const parser = new UserAgent().hydrate(source);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(parser.Agent));
});
server.listen(3000);
ESM usage (Node 18+):
import express from 'express';
import { express as useragent } from 'express-useragent';
const app = express();
app.use(useragent());
app.get('/', (req, res) => {
res.json({
browser: req.useragent?.browser,
os: req.useragent?.os,
});
});
app.listen(3000);
Alternatively, you can import the whole namespace:
import express from 'express';
import * as useragent from 'express-useragent';
const app = express();
app.use(useragent.express());
app.get('/', (req, res) => {
res.json({
browser: req.useragent?.browser,
os: req.useragent?.os,
});
});
app.listen(3000);
CommonJS (require) still supports the default export pattern used in older examples:
const express = require('express');
const useragent = require('express-useragent');
const app = express();
app.use(useragent.express());
app.get('/', (req, res) => {
res.json({
browser: req.useragent?.browser,
os: req.useragent?.os,
});
});
app.listen(3000);
import { express as useragent } from 'express-useragent';
app.use(useragent());
import * as useragent from 'express-useragent';
app.use(useragent.express());
const useragent = require('express-useragent');
app.use(useragent.express());
import useragent from 'express-useragent' returned an object with an .express() method used as middleware.express (and alias useragentMiddleware). Use one of:
import { express as useragent } from 'express-useragent' → app.use(useragent())import * as useragent from 'express-useragent' → app.use(useragent.express())require('express-useragent').express() continues to work unchanged.See more end-to-end demos under examples/:
examples/server.ts — Express middleware demoexamples/http.ts — raw Node HTTP samplenew UserAgent() — build a fresh parser instance.useragent.parse(source) — quick parse returning the agent snapshot.useragent.express() — Express-compatible middleware that hydrates req.useragent and res.locals.useragent.parser.Agent — normalized fingerprint with convenience booleans (isMobile, isBot, etc.).Sample payload:
{
"isMobile": false,
"isDesktop": true,
"isBot": false,
"browser": "Chrome",
"version": "118.0.0",
"os": "macOS Sonoma",
"platform": "Apple Mac",
"source": "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_0)..."
}
The build exports drop-in browser bundles under dist/browser/:
express-useragent.global.js — readable IIFE that exposes window.UserAgent and window.useragent.express-useragent.global.min.js — minified version of the same API.<script src="/vendor/express-useragent.global.min.js"></script>
<script>
const agent = new UserAgent().parse(navigator.userAgent);
console.log(agent.browser, agent.version);
</script>
Prefer consuming the ESM/CJS entry from your bundler when possible:
import { UserAgent } from 'express-useragent';
const agent = new UserAgent().parse(navigator.userAgent);
npm install # install dependencies
npm run lint # lint the TypeScript sources, tests, and examples
npm run typecheck # run the TypeScript compiler in noEmit mode
npm test # execute Vitest (includes adapted legacy suites)
npm run build # emit dist/ (CJS, ESM, d.ts, browser bundles)
Examples for manual testing:
npm run http # raw Node HTTP sample
npm run express # Express middleware demo
npm run simple # CLI parsing helper
Bug reports and PRs are welcome. When submitting changes, please include:
tests/ covering new parsing behaviour.npm test and npm run lint output or reproduction steps.See CONTRIBUTING.md for detailed guidelines, including how to update the bot list.
MIT © Aleksejs Gordejevs and contributors.