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

idle-ninja

v1.1.0

Published

The High-Performance, Cross-Tab Inactivity Tracker built for modern web applications.

Readme

🥷 idle-ninja

npm version Build Status Ko-Fi Buy Me A Coffee

The High-Performance, Cross-Tab Inactivity Tracker built for modern web applications.

idle-ninja detects when a user has walked away from their device. It's essential for banking apps, medical portals, or secure internal tools. Unlike older trackers that destroy browser performance by listening to every single mouse twitch, idle-ninja is highly optimized and built for modern web standards.

✨ Premium Features

  • Zero Memory Leaks (Smart Throttling): Older libraries crash pages by firing events 1,000 times a second. idle-ninja uses requestAnimationFrame to batch activity checks, keeping CPU usage at absolute zero.
  • Multi-Tab Leader Election: If a user has 5 tabs open to your app, older libraries run 5 separate timers. idle-ninja uses localStorage to elect one "leader" tab to run the timer, syncing activity across all tabs to save battery life.
  • "Second Screen" Awareness: It utilizes the Page Visibility API. If the tab is hidden but the session is active in another tab, the timers adjust intelligently to avoid unnecessary work.
  • Grace Period Hooks: It doesn't just log you out abruptly. It features built-in warning thresholds so you can prompt users to stay logged in, complete with a live countdown mechanism.
  • Keep-Alive Syncing: Built-in throttling for backend session extension requests, ensuring your backend doesn't get flooded with pings while the user is active.

📦 Installation

npm install idle-ninja

🚀 Quick Start

Initialize idle-ninja as early as possible in your application lifecycle.

import { IdleNinja } from 'idle-ninja';

const ninjaTracker = IdleNinja.start({
  // Time formats support 'm' (minutes), 's' (seconds), or raw milliseconds
  warningAt: '13m',
  logoutAt: '15m',

  // Extend backend session at most once every 5 minutes during continuous activity
  keepAliveInterval: '5m',
  onKeepAlive: () => {
    fetch('/api/extend-session', { method: 'POST' });
  },

  // Fires every second during the warning period (13m -> 15m)
  onWarning: (remainingTime) => {
    const secondsLeft = Math.ceil(remainingTime / 1000);
    console.warn(`Are you still there? Logging out in ${secondsLeft}s`);
    // e.g., document.getElementById('warning-modal').style.display = 'block';
  },

  // Fires when the logout threshold is reached
  onLogout: () => {
    console.error('Session expired.');
    window.location.href = '/login?reason=timeout';
  },

  // Fires when the user becomes active after previously being idle
  onActive: () => {
    console.log('Welcome back! User is active again.');
    // e.g., document.getElementById('warning-modal').style.display = 'none';
  },
});

// To stop the tracker manually later:
// ninjaTracker.stop();

⚙️ Configuration API

| Option | Type | Default | Description | | :-------------------- | :-------------------------------- | :-------------------- | :------------------------------------------------------------------- | | warningAt | string | number | 13m | Time of inactivity before onWarning is triggered. | | logoutAt | string | number | 15m | Time of inactivity before onLogout is triggered. | | keepAliveInterval | string | number | 5m | Minimum time between onKeepAlive calls during continuous activity. | | onWarning | (remainingTime: number) => void | () => {} | Fires continuously (every 1s) during the warning period. | | onLogout | () => void | () => {} | Fires when logoutAt is reached. | | onActive | () => void | () => {} | Fires when user becomes active after being in a warning state. | | onKeepAlive | () => void \| Promise<void> | () => {} | Throttled hook for sending server pings to extend a session. | | storageKey | string | 'idle-ninja-leader' | The localStorage key used for leader election. | | leaderCheckInterval | number | 5000 | How often followers check if the leader tab is still alive (in ms). |

☕ Support

If you find idle-ninja helpful and want to support its continued development, I would greatly appreciate a coffee!

  • Ko-fi
  • Buy Me a Coffee

📄 License

MIT License © 2026 Mikael-tenshio