@cookiefirst/fastdetect
v1.0.5
Published
High-performance device detection library optimized for API usage with comprehensive device, browser, and OS detection
Readme
FastDetect 🚀
High-performance device detection library optimized for API usage with comprehensive device, browser, and OS detection.
✨ Features
- 🏃♂️ High Performance: Optimized for 10,000+ detections per second with sub-millisecond response times
- 🎯 Comprehensive Detection: Device types, brands, models, browsers, operating systems, and bots
- 💾 Smart Caching: Built-in LRU cache with configurable size for optimal memory usage
- 📱 Mobile-First: Optimized patterns for modern mobile devices and emerging technologies
- 🤖 AI-Ready: Detection for modern AI crawlers (GPTBot, ClaudeBot, PerplexityBot)
- 🌳 Tree-Shakeable: Modular architecture allows importing only needed components
- 📘 TypeScript: Full type definitions with comprehensive IntelliSense support
- 🔒 Zero Dependencies: No external runtime dependencies for maximum security
- ⚖️ AGPL-3.0 Licensed: Free software with copyleft protection
🚀 Installation
npm install @cookiefirst/fastdetectyarn add @cookiefirst/fastdetectpnpm add @cookiefirst/fastdetect📖 Quick Start
Basic Usage
import FastDetect from '@cookiefirst/fastdetect';
const detector = new FastDetect();
const result = detector.parse('Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1');
console.log(result);
// Output:
// {
// browser: { name: 'Safari', version: '16.6', major: '16', engine: 'WebKit', isMobile: true },
// os: { name: 'iOS', version: '16.6', family: 'iOS' },
// device: { type: 'smartphone', brand: 'Apple', model: 'iPhone' },
// bot: { isBot: false, name: null, category: null },
// userAgent: '...',
// timestamp: 1703932800000
// }Modular Usage (Tree-Shaking Optimized)
import { BrowserParser, DeviceParser } from '@cookiefirst/fastdetect';
const browserParser = new BrowserParser();
const deviceParser = new DeviceParser();
const browser = browserParser.parse(userAgent);
const device = deviceParser.parse(userAgent);Express.js Middleware
import express from 'express';
import FastDetect from '@cookiefirst/fastdetect';
const app = express();
const detector = new FastDetect({ cacheSize: 5000 });
app.use((req, res, next) => {
req.device = detector.parse(req.headers['user-agent'] || '');
next();
});
app.get('/api/analytics', (req, res) => {
const { device } = req;
// Log device information for analytics
console.log(`Device: ${device.device.type}, Browser: ${device.browser.name}`);
res.json({ success: true });
});🔧 API Reference
FastDetect Class
Constructor
new FastDetect(options?: ParseOptions)Options:
cacheSize?: number- LRU cache size (default: 1000)skipCache?: boolean- Disable caching (default: false)detailed?: boolean- Enable detailed parsing (default: false)
Methods
parse(userAgent: string, options?: ParseOptions): DetectionResult
Parse complete device information from user agent string.
const result = detector.parse('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');parseBrowser(userAgent: string): BrowserInfo
Parse browser information only (lightweight).
const browser = detector.parseBrowser(userAgent);
// { name: 'Chrome', version: '91.0.4472.124', major: '91', engine: 'Blink' }parseDevice(userAgent: string): DeviceInfo
Parse device information only.
const device = detector.parseDevice(userAgent);
// { type: 'smartphone', brand: 'Apple', model: 'iPhone 14 Pro' }parseOS(userAgent: string): OSInfo
Parse operating system information only.
const os = detector.parseOS(userAgent);
// { name: 'iOS', version: '16.6', family: 'iOS' }parseBot(userAgent: string): BotInfo
Parse bot/crawler information only.
const bot = detector.parseBot(userAgent);
// { isBot: true, name: 'Googlebot', category: 'search-engine' }Quick Detection Methods
detector.isMobile(userAgent) // boolean
detector.isTablet(userAgent) // boolean
detector.isDesktop(userAgent) // boolean
detector.isBot(userAgent) // booleanCache Management
detector.clearCache() // Clear cache
detector.getCacheStats() // Get cache statistics📊 Supported Detections
Device Types
- Smartphones - iPhone, Android phones, etc.
- Tablets - iPad, Android tablets, Surface tablets
- Desktops - Windows, macOS, Linux computers
- Smart TVs - Android TV, webOS, Tizen, Roku, Apple TV
- Gaming Consoles - PlayStation, Xbox, Nintendo Switch, Steam Deck
- VR/AR Headsets - Meta Quest, Apple Vision Pro, HTC Vive
- Wearables - Apple Watch, Galaxy Watch, Wear OS
- E-readers - Kindle, Kobo, Nook
- Automotive - Android Automotive, CarPlay systems
- IoT Devices - Smart home devices, embedded systems
Browsers (50+ supported)
- Desktop: Chrome, Firefox, Safari, Edge, Opera, Internet Explorer
- Mobile: Chrome Mobile, Safari Mobile, Samsung Internet, UC Browser
- WebViews: Android WebView, iOS WebView, Facebook Browser
Operating Systems (30+ supported)
- Desktop: Windows (7-11), macOS, Linux distributions
- Mobile: iOS, iPadOS, Android, Windows Phone
- Specialized: Chrome OS, Tizen, webOS, KaiOS
Device Brands (100+ supported)
- Mobile: Apple, Samsung, Google, Huawei, Xiaomi, OPPO, vivo, OnePlus
- Desktop: Dell, HP, Lenovo, ASUS, Microsoft Surface
- Gaming: Sony, Microsoft, Nintendo, Valve
Bots & Crawlers (50+ supported)
- Search Engines: Googlebot, Bingbot, Yahoo Slurp, Baidu Spider
- AI Crawlers: GPTBot, ClaudeBot, PerplexityBot (2024-2025)
- Social Media: Facebook, Twitter, LinkedIn, Pinterest bots
- SEO Tools: Ahrefs, Semrush, Majestic crawlers
- Monitoring: UptimeRobot, Pingdom, DataDog
🎯 Performance
FastDetect is optimized for high-throughput API usage:
- Speed: 10,000+ detections per second
- Memory: < 2MB memory usage with default cache
- Latency: Sub-millisecond response time (P95 < 1ms)
- Accuracy: 99%+ accuracy for known devices
- Cache Hit Rate: 85-95% in typical usage
Benchmark Results
Device Detection Performance Test
─────────────────────────────────────
✓ Mobile Detection: 97,843 ops/sec
✓ Browser Parsing: 45,672 ops/sec
✓ Complete Parsing: 28,941 ops/sec
✓ Cache Hit: 892,456 ops/sec
✓ Memory Usage: 1.2MB (1000 entries)🔧 Configuration
Cache Configuration
const detector = new FastDetect({
cacheSize: 2000, // Increase cache for high-traffic APIs
skipCache: false // Enable caching for better performance
});
// Monitor cache performance
const stats = detector.getCacheStats();
console.log(`Cache hit rate: ${stats.hitRate}%`);Memory Management
// Clear cache periodically in long-running processes
setInterval(() => {
const stats = detector.getCacheStats();
if (stats.hitRate < 50) {
detector.clearCache(); // Clear ineffective cache
}
}, 300000); // Every 5 minutesCache sizing and tradeoffs
- What the cache does: Stores parsed results by exact user agent string for O(1) reuse. Great when UA strings repeat; less useful when every request is unique.
- Memory vs. speed: Larger caches increase hit rate (more reuse) but consume more memory. With typical detection results, expect roughly ~0.7–0.9 KB per cached entry. For example, a cacheSize of 5,000 used ~7.5 MB in our stress test with 10,000 unique UAs.
- When to increase cache: High-traffic APIs with meaningful UA repetition (e.g., mobile apps, crawlers, corporate fleets). Aim for hitRate ≥ 80%.
- When to decrease/disable cache: Workloads with many unique UAs (e.g., logs/backfills). If hitRate < 50%, consider smaller cache or disabling per-call.
Recommended defaults by environment:
- Serverless/function:
cacheSize: 200–1000 - Container/service (2–4 GB RAM):
cacheSize: 1000–5000 - Batch/log processing (low repetition): use
skipCache: trueon parse calls
Examples
// 1) Tune via env var with safe default
const detector = new FastDetect({
cacheSize: Number(process.env.FD_CACHE_SIZE ?? 1000)
});
// 2) Disable caching for specific calls (e.g., batch jobs)
detector.parse(ua, { skipCache: true });
// 3) Monitor and adjust based on hit rate
const { hitRate, size, capacity } = detector.getCacheStats();
if (hitRate < 50) {
// Consider recreating detector with a smaller cacheSize or using skipCache
}🚦 Browser Usage Warning
⚠️ Important: FastDetect is optimized for server-side usage. For browser usage, consider the lightweight alternatives:
// ✅ Recommended for browsers (lightweight)
import { BrowserParser } from 'fastdetect/parsers/browser';
const browserParser = new BrowserParser();
const browser = browserParser.parse(navigator.userAgent);📈 Migration Guide
From ua-parser-js
// Before (ua-parser-js)
import { UAParser } from 'ua-parser-js';
const parser = new UAParser();
const result = parser.setUA(userAgent).getResult();
// After (FastDetect)
import FastDetect from '@cookiefirst/fastdetect';
const detector = new FastDetect();
const result = detector.parse(userAgent);
// Mapping
result.browser.name // ✓ Same
result.device.type // ✓ Same concept
result.os.name // ✓ SameFrom mobile-detect
// Before (mobile-detect)
import MobileDetect from 'mobile-detect';
const md = new MobileDetect(userAgent);
const isMobile = md.mobile();
// After (FastDetect)
import FastDetect from '@cookiefirst/fastdetect';
const detector = new FastDetect();
const isMobile = detector.isMobile(userAgent);🧪 Testing
npm test # Run all tests
npm run test:coverage # Run with coverage
npm run benchmark # Performance benchmarks📄 License
AGPL-3.0 License - see LICENSE file for details.
🤝 Contributing
Contributions are welcome! Please read our Contributing Guide for details.
Development Setup
git clone https://github.com/cookiefirst-dds/fastdetect.git
cd fastdetect
npm install
npm run build
npm testAdding New Device Patterns
- Add pattern to parser: Update the relevant parser in
src/parsers/ - Add test cases: Create comprehensive test cases
- Update documentation: Document new detections
- Performance test: Ensure no regression in performance
🔍 Examples
Real-World Usage Examples
API Analytics Service
import FastDetect from '@cookiefirst/fastdetect';
import express from 'express';
const app = express();
const detector = new FastDetect({ cacheSize: 10000 });
// Analytics middleware
app.use('/api', (req, res, next) => {
const userAgent = req.headers['user-agent'];
const detection = detector.parse(userAgent || '');
// Log for analytics
console.log({
timestamp: Date.now(),
deviceType: detection.device.type,
browser: detection.browser.name,
os: detection.os.name,
isBot: detection.bot.isBot
});
// Add to request for downstream handlers
req.deviceInfo = detection;
next();
});
app.get('/api/content', (req, res) => {
const { deviceInfo } = req;
// Serve optimized content based on device
if (deviceInfo.device.type === 'smartphone') {
res.json({ content: 'mobile-optimized-content' });
} else {
res.json({ content: 'desktop-content' });
}
});Bot Detection Service
import FastDetect from '@cookiefirst/fastdetect';
const detector = new FastDetect();
function handleRequest(userAgent: string) {
const detection = detector.parse(userAgent);
if (detection.bot.isBot) {
console.log(`Bot detected: ${detection.bot.name} (${detection.bot.category})`);
// Handle different bot types
switch (detection.bot.category) {
case 'search-engine':
return { action: 'allow', priority: 'high' };
case 'ai-crawler':
return { action: 'rate-limit', priority: 'medium' };
case 'seo-tool':
return { action: 'allow', priority: 'low' };
default:
return { action: 'block', priority: 'none' };
}
}
return { action: 'allow', priority: 'high' };
}Device-Specific Feature Detection
import FastDetect from '@cookiefirst/fastdetect';
const detector = new FastDetect();
function getAvailableFeatures(userAgent: string) {
const detection = detector.parse(userAgent);
const features = [];
// Device-specific features
switch (detection.device.type) {
case 'smartphone':
features.push('touch', 'geolocation', 'camera', 'push-notifications');
break;
case 'tablet':
features.push('touch', 'large-screen', 'orientation');
break;
case 'desktop':
features.push('keyboard', 'mouse', 'large-screen', 'file-system');
break;
case 'smart-tv':
features.push('large-screen', 'remote-control');
break;
}
// Browser-specific features
if (detection.browser.name === 'Chrome' &&
parseInt(detection.browser.major || '0') >= 90) {
features.push('webrtc', 'webassembly', 'service-worker');
}
return features;
}Batch Processing Example
import FastDetect from '@cookiefirst/fastdetect';
const detector = new FastDetect({ cacheSize: 5000 });
// Process large user agent logs efficiently
function processUserAgentLogs(userAgents: string[]) {
const results = [];
const uniqueUAs = [...new Set(userAgents)]; // Deduplicate for performance
// Process unique user agents once
const detectionMap = new Map();
for (const ua of uniqueUAs) {
detectionMap.set(ua, detector.parse(ua));
}
// Map results back to original array
for (const ua of userAgents) {
results.push(detectionMap.get(ua));
}
return results;
}🔬 Advanced Configuration
Custom Pattern Extensions
import FastDetect from '@cookiefirst/fastdetect';
import { DeviceParser } from '@cookiefirst/fastdetect/parsers/device';
// Extend DeviceParser for custom patterns
class CustomDeviceParser extends DeviceParser {
parse(userAgent: string) {
const result = super.parse(userAgent);
// Add custom business logic
if (userAgent.includes('CustomDevice')) {
result.brand = 'CustomBrand';
result.model = 'Custom Model';
}
return result;
}
}
const detector = new FastDetect();
// Replace internal parser (advanced usage)
detector['deviceParser'] = new CustomDeviceParser();Performance Monitoring
import FastDetect from '@cookiefirst/fastdetect';
const detector = new FastDetect({ cacheSize: 2000 });
// Monitor performance metrics
setInterval(() => {
const stats = detector.getCacheStats();
console.log('FastDetect Performance Metrics:');
console.log(`Cache Size: ${stats.size}/${stats.capacity}`);
console.log(`Hit Rate: ${stats.hitRate}%`);
console.log(`Total Hits: ${stats.hits}`);
console.log(`Total Misses: ${stats.misses}`);
// Alert if performance degrades
if (stats.hitRate < 70) {
console.warn('Cache hit rate below 70%, consider increasing cache size');
}
}, 60000); // Every minute🌐 Framework Integration
Next.js Integration
// pages/api/device-info.ts
import type { NextApiRequest, NextApiResponse } from 'next';
import FastDetect from '@cookiefirst/fastdetect';
const detector = new FastDetect();
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const userAgent = req.headers['user-agent'] || '';
const deviceInfo = detector.parse(userAgent);
res.status(200).json(deviceInfo);
}
// Middleware example
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import FastDetect from '@cookiefirst/fastdetect';
const detector = new FastDetect();
export function middleware(request: NextRequest) {
const userAgent = request.headers.get('user-agent') || '';
const deviceInfo = detector.parse(userAgent);
// Add device info to headers
const response = NextResponse.next();
response.headers.set('x-device-type', deviceInfo.device.type);
response.headers.set('x-is-mobile', deviceInfo.device.type === 'smartphone' ? 'true' : 'false');
return response;
}Fastify Plugin
import fastify from 'fastify';
import FastDetect from '@cookiefirst/fastdetect';
const detector = new FastDetect();
// Create Fastify plugin
const deviceDetectionPlugin = async (fastify: any) => {
fastify.decorateRequest('device', null);
fastify.addHook('preHandler', async (request: any) => {
const userAgent = request.headers['user-agent'] || '';
request.device = detector.parse(userAgent);
});
};
const app = fastify();
app.register(deviceDetectionPlugin);
app.get('/api/info', async (request: any, reply) => {
return { deviceInfo: request.device };
});📊 Type Definitions
Complete TypeScript Interfaces
interface DetectionResult {
browser: BrowserInfo;
os: OSInfo;
device: DeviceInfo;
bot: BotInfo;
userAgent: string;
timestamp: number;
}
interface BrowserInfo {
name: string;
version: string | null;
major: string | null;
engine?: string;
isMobile?: boolean;
isWebView?: boolean;
}
interface DeviceInfo {
type: 'smartphone' | 'tablet' | 'desktop' | 'laptop' | 'smart-tv' |
'gaming-console' | 'wearable' | 'iot-device' | 'automotive' |
'vr-headset' | 'e-reader' | 'unknown';
brand: string;
model: string | null;
marketingName?: string;
}
interface OSInfo {
name: string;
version: string | null;
family?: string;
architecture?: string;
}
interface BotInfo {
isBot: boolean;
name: string | null;
category: string | null;
company?: string;
purpose?: string;
}🚀 Performance Tips
Optimization Best Practices
Use Appropriate Cache Size
// High-traffic API (>10k requests/min) const detector = new FastDetect({ cacheSize: 5000 }); // Low-traffic API (<1k requests/min) const detector = new FastDetect({ cacheSize: 500 });Deduplicate User Agents
// Efficient batch processing const uniqueUAs = [...new Set(userAgents)]; const results = uniqueUAs.map(ua => detector.parse(ua));Use Quick Detection Methods
// Fast path for simple checks if (detector.isMobile(userAgent)) { // Mobile-specific logic } else { // Desktop logic }Monitor Cache Performance
const stats = detector.getCacheStats(); if (stats.hitRate < 80) { // Consider increasing cache size or investigating patterns }
🛠️ Troubleshooting
Common Issues
Q: High memory usage A: Reduce cache size or clear cache periodically
detector.clearCache(); // Clear when hit rate is lowQ: Low cache hit rate A: User agents are highly diverse; increase cache size
const detector = new FastDetect({ cacheSize: 3000 });Q: Inaccurate detection A: Please report with user agent string for pattern updates
Q: Bundle size too large A: Use modular imports for tree-shaking
import { BrowserParser } from '@cookiefirst/fastdetect/parsers/browser';📞 Support
- 🐛 Bug Reports: GitHub Issues
- 💡 Feature Requests: GitHub Discussions
🏆 Acknowledgments
Note: Acknowledgments reflect inspiration for patterns and API design. No code was copied from these sources.
- 51Degrees - Device database inspiration
- Matomo Device Detector - Pattern organization concepts
- ua-parser-js - API design reference
- Bowser - Performance optimization techniques
Made with ❤️ for the JavaScript community
FastDetect is optimized for production API usage. Star ⭐ us on GitHub if this project helps you!
