npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@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.

npm version TypeScript AGPL-3.0 License Bundle Size

✨ 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/fastdetect
yarn add @cookiefirst/fastdetect
pnpm 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)       // boolean

Cache 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 minutes

Cache 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: true on 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         // ✓ Same

From 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 test

Adding New Device Patterns

  1. Add pattern to parser: Update the relevant parser in src/parsers/
  2. Add test cases: Create comprehensive test cases
  3. Update documentation: Document new detections
  4. 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

  1. 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 });
  2. Deduplicate User Agents

    // Efficient batch processing
    const uniqueUAs = [...new Set(userAgents)];
    const results = uniqueUAs.map(ua => detector.parse(ua));
  3. Use Quick Detection Methods

    // Fast path for simple checks
    if (detector.isMobile(userAgent)) {
      // Mobile-specific logic
    } else {
      // Desktop logic
    }
  4. 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 low

Q: 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

🏆 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!