@ngrithms/idle

Signal-first user-inactivity detector for Angular — standalone, SSR-safe, zero deps.

npm install @ngrithms/idle

This page runs @ngrithms/idle v0.4 with intentionally-short demo timings: 5 s to idle, then 10 s more to timedOut. Stop interacting and watch the state below shift. Move your mouse, type, or click to revive. Open the page in a second tab to see multiTabSync in action — activity in either tab keeps both alive.

Current state

active
Watching for 0s of activity quiet

Conditional rendering with *ngrIfIdle

Three cards — only the one matching the current state mounts:

ACTIVE

The user is interacting normally. Render features that depend on a live session here.

Quick controls

Watching paused

Inside the library

The live signals exposed by IdleService. Updates push reactively as the state machine transitions and as you interact with the page.

Setup

provideIdle({
  idleAfter: 5_000,   // short for the demo;
  timeout: 10_000,    // real apps use minutes
  pauseWhenHidden: true,
  multiTabSync: true,
  autoStart: true,
});

Live signals

{
  "state": "active",
  "countdown": 0,
  "lastActivity": 1779028727805,
  "interrupts": []
}

Quick start

// src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideIdle } from '@ngrithms/idle';

export const appConfig: ApplicationConfig = {
  providers: [
    provideIdle({
      idleAfter: 5 * 60_000,   // 5 minutes to idle
      timeout: 30_000,         // 30 s warning window
      multiTabSync: true,
    }),
  ],
};

// In any component
import { Component, inject } from '@angular/core';
import { IdleService, IfIdleDirective } from '@ngrithms/idle';

@Component({
  imports: [IfIdleDirective],
  template: `
    <div *ngrIfIdle>
      Are you still there? Logging out in {{ idle.countdown() }}s...
      <button (click)="idle.reset()">Stay signed in</button>
    </div>
    <div *ngrIfIdle="'timedOut'">
      Session expired. <a routerLink="/login">Sign in again</a>.
    </div>
  `,
})
export class SessionGuard {
  protected readonly idle = inject(IdleService);
}

See the full README for multi-tab sync flags, the sleep watchdog, the onSystemSleep option, and the @ngrithms/idle/keepalive secondary entry point for server-side session syncing.

Learn more