A modern, lightweight JavaScript library for accurate device detection with full User-Agent Client Hints support. Detects device types (mobile, tablet, desktop, smart TV, console, wearable, bot) with enhanced iOS detection including iPad desktop mode recognition and SSR compatibility.
- Enhanced iOS Detection: Accurately detects iOS devices including iPad desktop mode with Client Hints
- Client Hints Native: Full support for User-Agent Client Hints (low & high entropy) with progressive fallback
- Lightweight & Fast: Only a few KB minified, zero dependencies, pure JavaScript
- Universal Compatibility: Works seamlessly in browser, Node.js, SSR frameworks, and AMD environments
- Comprehensive Device Detection: Mobile, tablet, desktop, smart TV, console, wearable, and bot traffic
- Detailed Insights: Reports OS name/version and browser name/version with Client Hints precision
- Server-Side Ready: Accepts injected user-agent strings and hints for Express, Next.js, and testing frameworks
- Future-Proof: Handles reduced UA strings and privacy-focused browser features
- Modern Architecture: ES6+ class-based design with full backward compatibility
npm install @varienos/device-detector-js<script src="https://unpkg.com/@varienos/device-detector-js@latest/dist/device-detector.min.js"></script><script src="dist/device-detector.min.js"></script>
<script>
// Using the global instance
if (deviceDetector.isMobile()) {
console.log('This is a mobile device!');
}
// Or create a new instance
const detector = new DeviceDetector();
console.log('Device type:', detector.getDeviceType());
</script>import DeviceDetector from '@varienos/device-detector-js';
const detector = new DeviceDetector();
if (detector.isMobile()) {
console.log('Mobile device detected!');
}const DeviceDetector = require('@varienos/device-detector-js');
const detector = new DeviceDetector();
console.log('Device info:', detector.getDeviceInfo());// Express or Next.js API route
app.get('/api/device', (req, res) => {
const detector = new DeviceDetector({
userAgent: req.headers['user-agent']
});
res.json(detector.getDeviceInfo());
});import DeviceDetector from '@varienos/device-detector-js';
function App() {
const device = new DeviceDetector().getDeviceInfo();
return (
<div>
<h1>Device: {device.deviceType}</h1>
{device.isMobile && <MobileLayout />}
{device.isDesktop && <DesktopLayout />}
</div>
);
}import { useMemo } from 'react';
import DeviceDetector from '@varienos/device-detector-js';
function useDevice() {
return useMemo(() => new DeviceDetector().getDeviceInfo(), []);
}
function MyComponent() {
const device = useDevice();
return (
<div className={`layout-${device.deviceType}`}>
{device.isMobile ? <MobileNav /> : <DesktopNav />}
</div>
);
}// app/layout.jsx (App Router)
import DeviceDetector from '@varienos/device-detector-js';
import { headers } from 'next/headers';
export default function RootLayout({ children }) {
const userAgent = headers().get('user-agent') || '';
const deviceType = new DeviceDetector({ userAgent }).getDeviceType();
return (
<html data-device={deviceType}>
<body>{children}</body>
</html>
);
}const detector = new DeviceDetector({
userAgent, // Optional string
userAgentData, // Optional low-entropy hints
highEntropyValues // Optional pre-fetched high-entropy hints
});userAgent: Inject a custom user-agent string (SSR, tests, logs).userAgentData: Provide parsednavigator.userAgentDatavalues when the environment cannot expose the real object.highEntropyValues: Supply high-entropy UA-CH data gathered elsewhere (e.g., server pre-fetch).
isMobile()- Returnstrueif the device is mobileisTablet()- Returnstrueif the device is a tabletisDesktop()- Returnstrueif the device is a desktop-class browserisSmartTV()- Returnstrueif the device matches smart TV signaturesisConsole()- Returnstrueif the device is a game consoleisWearable()- Returnstrueif the device is a wearable/watchisBot()- Returnstruefor known crawler and bot user agents
isAndroid()- Returnstrueif the device runs AndroidisIOS()- Returnstrueif the device runs iOS or iPadOSisWindowsPhone()- Returnstrueif the device is Windows Phone (legacy)
getDeviceType()- Returns'mobile' | 'tablet' | 'desktop' | 'smarttv' | 'console' | 'wearable' | 'bot'getDeviceInfo()- Returns a comprehensive info object (see below)getOsInfo()- Returns{ name, version }derived from UA/Client HintsgetBrowserInfo()- Returns{ name, version }for the detected browserrefreshHighEntropyValues(hints?)- Fetches additional UA-CH data and caches it (Promise)awaitHighEntropyValues()- Resolves once the constructor-triggered high-entropy fetch completesgetHighEntropyValues()- Returns cached high-entropy data ornull
const detector = new DeviceDetector();
console.log(detector.getDeviceInfo());
// Example output:
{
isMobile: false,
isTablet: true,
isDesktop: false,
isAndroid: false,
isIOS: true,
isWindowsPhone: false,
isSmartTV: false,
isConsole: false,
isWearable: false,
isBot: false,
deviceType: 'tablet',
os: { name: 'iOS', version: '16.4' },
browser: { name: 'Safari', version: '16.4' },
userAgent: 'Mozilla/5.0 (iPad; CPU OS 16_4 like Mac OS X)...',
brands: [],
highEntropyValues: null
}- Chrome, Edge, and other Chromium-based browsers (recent releases)
- Firefox (recent releases)
- Safari on macOS and iOS
- Legacy Internet Explorer 11 (no official guarantee beyond basic UA checks)
- Mobile browsers that still expose a user-agent string
- The library consults
navigator.userAgentData(User-Agent Client Hints) when the browser exposes it, then falls back to classic user-agent parsing. Results depend on what the browser chooses to share. - User-agent strings are being reduced over time; keep detection logic as a progressive enhancement rather than a security boundary.
isWindowsPhone()stays available for existing consumers, but Windows Phone is officially unsupported. Monitor analytics before relying on it in new features.
The library now provides improved iOS detection that handles modern scenarios:
- Client Hints Only: Detects iOS even when only
userAgentData.platformis available (SSR scenarios) - iPad Desktop Mode: Accurately identifies iPad when "Request Desktop Website" is enabled by checking
highEntropyValues.model - High-Entropy Fallback: Examines device model information for iOS indicators
- Progressive Enhancement: Uses platform signals first, then falls back to user-agent string parsing
This ensures reliable iOS detection across server-side rendering, modern browsers with reduced UA strings, and iPad's desktop mode.
# Install dependencies
npm install
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run with coverage
npm test -- --coverage# Install dependencies
npm install
# Start the live example server
npm run dev
# Lint code
npm run lint
# Build minified bundle
npm run buildThis project is licensed under the MIT License - see the LICENSE file for details.