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

@jayoncode/browser-lifecycle

v0.3.3

Published

Typed browser session lifecycle for modern web apps — one API for visibility, focus, connectivity, idle, page lifecycle, and cross-tab, with optional session intelligence and DX. Observe browser state. Derive session intelligence. React with confidence.

Readme

Browser Lifecycle — Typed, framework-agnostic browser session lifecycle for modern web apps.

Observe browser state. Derive session intelligence. React with confidence.

@jayoncode/browser-lifecycle — typed, framework-agnostic browser session lifecycle for modern web apps.

npm version license docs Become a Sponsor

One API for visibility, focus, connectivity, idle, page lifecycle, and cross-tab — with optional session intelligence and DX. Works with React, Vue, Angular, Svelte, Next.js, and vanilla JavaScript.

One session. One snapshot. One event stream.
Everything else is derived.

Observe → Understand → React

Most libraries stop at browser events. Browser Lifecycle continues:

Browser APIs
    ↓
Normalized Session
    ↓
Session Intelligence (opt-in)
    ↓
Developer APIs (opt-in)

| Pillar | What you get | | -------------- | --------------------------------------------------- | | Observe | Normalize browser lifecycle into one consistent API | | Understand | Transform signals into meaningful session insights | | React | Wait, conditions, resilience, plugins, playground |

Five capabilities

| Card | What it is | | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | Unified Browser Lifecycle | One typed session for visibility, focus, connectivity, idle, page lifecycle, and cross-tab — instead of scattered listeners | | Session Intelligence | Opt-in activity (active / idle) and page-local presence (available / away / unknown) | | Timeline | Bounded chronological history of session events | | Session Insights | Opt-in metrics and on-demand reports — not an analytics SDK | | Developer Experience | Wait, conditions, resilience, plugins, and an interactive playground |

Install

npm install @jayoncode/browser-lifecycle
pnpm add @jayoncode/browser-lifecycle
yarn add @jayoncode/browser-lifecycle

The problem it solves

Most apps slowly accumulate listeners like this:

document.addEventListener("visibilitychange", ...);
window.addEventListener("focus", ...);
window.addEventListener("blur", ...);
window.addEventListener("online", ...);
window.addEventListener("offline", ...);
// + custom idle timer + cleanup bugs on every route change

@jayoncode/browser-lifecycle replaces that sprawl with one session object.

Quick start — Observe first

import { createBrowserLifecycle } from "@jayoncode/browser-lifecycle";

const lifecycle = createBrowserLifecycle({
  autoStart: true,
  idleTimeout: 60_000,
});

lifecycle.on("page:hidden", () => {
  pausePolling();
  pauseMedia();
});

lifecycle.on("page:visible", () => {
  resumePolling();
});

lifecycle.on("session:idle", () => {
  lockSensitiveScreen();
});

lifecycle.on("connection:reconnect", () => {
  flushOfflineQueue();
});

const snapshot = lifecycle.getSnapshot();

// Sync teardown — do not reuse the instance
lifecycle.dispose();

Zero-cost until you ask

Core observation stays lightweight. Session intelligence and developer experience are completely opt-in — you only pay for what you use. Creating a session does not allocate Activity, Presence, Timeline, Metrics, or Reports.

const lifecycle = createBrowserLifecycle({ autoStart: true });
// lean core only

const timeline = createTimelineApi(lifecycle);
// cost starts here

Understand & React (opt-in factories)

Flush work when the network comes back

import { createBrowserLifecycle, createResilienceApi } from "@jayoncode/browser-lifecycle";

const lifecycle = createBrowserLifecycle({ autoStart: true });
const resilience = createResilienceApi(lifecycle);

resilience.onReconnect(() => {
  flushOfflineQueue();
});

resilience.onWake(() => {
  refreshStaleData();
});

Wait until the tab is visible before heavy work

import { createBrowserLifecycle, createWaitApi } from "@jayoncode/browser-lifecycle";

const lifecycle = createBrowserLifecycle({ autoStart: true });
const wait = createWaitApi(lifecycle);

await wait.untilVisible({ timeoutMs: 10_000 });
startExpensiveHydration();

Session insights — metrics without building your own counters

import {
  createBrowserLifecycle,
  createMetricsApi,
  createReportsApi,
  createTimelineApi,
} from "@jayoncode/browser-lifecycle";

const lifecycle = createBrowserLifecycle({ autoStart: true, idleTimeout: 30_000 });
const metrics = createMetricsApi(lifecycle);
const timeline = createTimelineApi(lifecycle);
const reports = createReportsApi({ metrics, timeline });

console.log(metrics.attention().score); // 0–100
console.log(reports.sessionSummary());

| Helper | Layer | What it solves | | --------------------- | -------------------- | ------------------------------------- | | createActivityApi | Session Intelligence | Active / idle facade | | createPresenceApi | Session Intelligence | Page-local available / away / unknown | | createTimelineApi | Timeline | Bounded event history | | createMetricsApi | Session Insights | Durations, counts, attention score | | createReportsApi | Session Insights | On-demand session summaries | | createWaitApi | Developer Experience | untilVisible, untilOnline, … | | createConditionsApi | Developer Experience | when.hidden(...), … | | createResilienceApi | Developer Experience | Reconnect / wake / restore |

createSessionHealthApi and createSessionPredictApi are experimental helpers — documented in the intelligence guide, not homepage flagships.

What this is not

  • Not multi-user / Slack-like presence — presence is page-local
  • Not an analytics or telemetry SDK — Session Insights stay in-process
  • Connectivity is advisory (navigator.onLine), not reachability
  • Not auth, routing, or storage

Framework adapters

Thin wrappers live in separate packages (dispose on unmount; client-only start):

  • @jayoncode/browser-lifecycle-react
  • @jayoncode/browser-lifecycle-vue
  • @jayoncode/browser-lifecycle-svelte
  • @jayoncode/browser-lifecycle-solid
  • @jayoncode/browser-lifecycle-angular

Documentation

Requirements

  • Node.js 20+ (for tooling)
  • Browsers: modern evergreen browsers; see browser support

Repository

https://github.com/itsjayoncode/joc · Package path: packages/browser-lifecycle

License

MIT © JayOnCode