Package overview
Observe browser state. Derive session intelligence. React with confidence.
Browser Lifecycle (@jayoncode/browser-lifecycle) normalizes browser session signals into one session, one snapshot, and one event stream — with optional session intelligence and DX on top.
One session. One snapshot. One event stream.
Everything else is derived.
Observe → Understand → React
Browser APIs
↓
Normalized Session
↓
Session Intelligence (opt-in)
↓
Developer APIs (opt-in)| Most libraries | Browser Lifecycle |
|---|---|
| Browser APIs → Events | Browser APIs → Normalized Session → Session Intelligence → Developer APIs |
| Pillar | Meaning |
|---|---|
| Observe | Normalize browser lifecycle into one consistent API |
| Understand | Transform signals into meaningful session insights |
| React | Build resilient apps with Wait, Conditions, Resilience, plugins |
Five capabilities
| Card | Distinction |
|---|---|
| Unified Browser Lifecycle | Foundation — visibility, focus, connectivity, idle, page lifecycle, cross-tab |
| Session Intelligence | Current derived state — activity + page-local presence |
| Timeline | Chronological session event history |
| Session Insights | Aggregates — metrics + reports (not an analytics SDK) |
| Developer Experience | How you react — Wait, Conditions, Resilience, plugins, playground |
When to use
- Pause media/polling when the tab hides; resume on visible
- Idle / session-timeout UX, connectivity-aware sync, cross-tab leadership
- One shared session instead of scattered
document/windowlisteners - Opt-in timeline, metrics, or wait helpers when you need them
When not to use
- You only need a one-off
visibilitychangein a tiny page (raw API may be enough) - Server-only Node services with no browser globals — create the session in the client bootstrap
- Product analytics / telemetry SDKs — this is session understanding, not an analytics product
- Multi-user presence — presence here is page-local (this browser session)
Features
- Visibility, focus, connectivity, idle, page lifecycle, and cross-tab behind one session
- Typed
on()/subscribe()events + readonlygetSnapshot() - SSR-safe capability detection before modules attach
- Plugins and opt-in intelligence / DX factories (zero-cost until you ask)
Zero-cost until you ask
Core observation stays lightweight. Session intelligence and developer experience allocate only after you call their factories.
import { createBrowserLifecycle, createTimelineApi } from "@jayoncode/browser-lifecycle";
const lifecycle = createBrowserLifecycle({ autoStart: true });
// lean core only
const timeline = createTimelineApi(lifecycle);
// cost starts hereSingle entrypoint
Everything imports from @jayoncode/browser-lifecycle (no feature subpaths). Tree-shaking still applies to unused exports.
Install
npm install @jayoncode/browser-lifecyclepnpm add @jayoncode/browser-lifecycleyarn add @jayoncode/browser-lifecycleExample: pause work when the tab is hidden
import { createBrowserLifecycle } from "@jayoncode/browser-lifecycle";
const lifecycle = createBrowserLifecycle({ autoStart: true });
lifecycle.on("page:hidden", () => {
pauseMedia();
flushTelemetry();
});
lifecycle.on("page:visible", () => {
resumeMedia();
});
// Form Intelligence composition (optional peer): save drafts when the tab hides —
// see [FI Patterns → Draft on tab hide](/packages/form-intelligence/modules/patterns#composition-draft-on-tab-hide-browser-lifecycle).
const { visibility, attention, connectivity } = lifecycle.getSnapshot();
// Sync teardown — disposed sessions must not be reused
lifecycle.dispose();One instance per tab replaces scattered document / window listeners with typed events and a readonly snapshot.
Problem → approach
| Typical pain | Browser Lifecycle |
|---|---|
document, window, and navigator listeners scattered across features | One createBrowserLifecycle() session with typed on() handlers |
| Tab visibility, focus, and connectivity each wired differently | Modules normalize signals; getSnapshot() exposes consolidated state |
| SSR crashes or silent no-ops when APIs are missing | Capability detection and SSR-safe defaults before modules attach |
Overview
createBrowserLifecycle() orchestrates browser signals through a module pipeline. Consumers subscribe to events or poll getSnapshot(); modules compose behind a single session boundary.
| Concern | API surface |
|---|---|
| Lifecycle | start(), stop(), dispose(), phase events |
| Signals | on(event, handler), once(), subscribe() for the full feed |
| State | getSnapshot() — readonly session state |
| Extension | Plugin hooks (onEvent on plugins), module configuration |
| Diagnostics | getRuntimeDiagnostics() for development |
Designed for SSR-safe capability detection and framework-agnostic integration (React, Vue, vanilla, etc.).
Always dispose
Call lifecycle.dispose() on route unmount or app shutdown (dispose is synchronous). Disposed sessions must not be reused — create a new instance.
SSR
Construct and start() only in the browser (or after hydration). Capability detection avoids crashing when document / window are missing; listeners still need a client environment.
Documentation path
Foundation
| # | Guide | Topics | Playground |
|---|---|---|---|
| 1 | Tutorial | Install, session, subscribe, dispose | Sandbox |
| 2 | Core concepts | Session, snapshot, events, modules | Sandbox / State |
Core modules (Observe)
| # | Guide | Topics | Playground |
|---|---|---|---|
| 3 | Visibility | Page Visibility API | Visibility |
| 4 | Focus | Window focus / blur | Focus |
| 5 | Idle | Activity + idle timeout | Idle |
| 6 | Connectivity | Advisory online/offline | Connectivity |
| 7 | Cross-tab | Leader election, tab messages | Cross Tab |
| 8 | Page lifecycle | Suspend / resume / restore | Lifecycle |
| 9 | Events | Subscription model | Events |
| 10 | Session core | Phases, startup order | Lifecycle |
Configuration and extension
| # | Guide | Topics | Playground |
|---|---|---|---|
| 11 | Plugins | Hooks, priority, diagnostics | Plugins |
| 12 | Core infrastructure | Config, capabilities, SSR | Configuration |
| 13 | Usage guide | Production patterns | Developer tools |
Understand & React (opt-in)
| # | Guide | Topics |
|---|---|---|
| 14 | Intelligence overview | Observe → Understand → React; factories |
| 15 | Activity / Presence | Session Intelligence (current derived state) |
| 16 | Timeline | Chronological history |
| 17 | Metrics / Reports | Session Insights (aggregates) |
| 18 | Wait / Conditions / Resilience | Developer Experience |
| 19 | Framework adapters | React, Vue, Svelte, Solid, Angular |
Package fit
| Requirement | Module / event |
|---|---|
| Pause background work on tab hide | page:hidden / page:visible |
| React to window focus | window:focus / window:blur |
| Offline-aware UI | connection:* (advisory) |
| Idle timeout / autosave triggers | Idle module |
| Session duration / attention | Metrics (Session Insights) |
| Event audit log | Timeline |
| Reconnect / wake / restore | Resilience |
| React / Vue / etc. bindings | Adapters |
| Cross-tab coordination | Cross-tab |
| Cross-cutting observation | Plugins |
| SSR / capability guards | Core infrastructure |
Reference
| Resource | Link |
|---|---|
| API (TypeDoc) | /packages/browser-lifecycle/api/ |
| Framework adapters | /packages/browser-lifecycle/modules/adapters |
| Framework examples | /packages/browser-lifecycle/examples/ |
| Best practices | /packages/browser-lifecycle/best-practices/ |
| Patterns | /packages/browser-lifecycle/patterns/ |
| FAQ | /packages/browser-lifecycle/faq/ |
| Playground guide | /packages/browser-lifecycle/playground/playground |
| Draft Desk | Official reference app — online/offline & session signals in a live form flow |
Version
Current npm version: v0.3.3 (@jayoncode/browser-lifecycle). See Migration and Changelog for release history.
