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

@uistate/perf

v1.0.0

Published

Non-invasive performance monitoring for @uistate/core stores: method wrapping, path heatmaps, timeline recording, browser overlay, downloadable JSON reports

Downloads

99

Readme

@uistate/perf

Non-invasive performance monitoring for @uistate/core stores.

Wraps store methods via the Prepend Dot-Path Pattern: zero core changes. Captures timing, path frequency, subscriber lifecycle, batch stats, and a full event timeline. Download the report as JSON for later analysis.

Install

npm install @uistate/perf

Quick Start

import { createEventState } from '@uistate/core';
import { createPerfMonitor, mountOverlay } from '@uistate/perf';

const store = createEventState({ count: 0 });

// 1. Wrap the store (non-invasive)
const perf = createPerfMonitor(store);

// 2. Inject browser overlay (optional)
const unmount = mountOverlay(perf, document.body);

// 3. Use the store normally (all calls are instrumented)
store.set('count', 1);
store.subscribe('count', (v) => console.log(v));

// 4. Download JSON report
perf.download();  // triggers browser download

// 5. Cleanup
perf.destroy();   // unwraps store methods
unmount();        // removes overlay

API

createPerfMonitor(store, options?)

Returns a monitor instance. Wraps set, get (opt-in), subscribe, batch, setMany.

Options:

| Option | Default | Description | |--------|---------|-------------| | maxEvents | 10000 | Ring buffer size for timeline events | | trackValues | false | Store values in timeline (increases memory) | | trackGets | false | Record get() calls (can be noisy) |

Monitor methods:

| Method | Description | |--------|-------------| | report() | Returns the full report object | | download(filename?) | Triggers browser JSON download | | reset() | Clears all recorded data | | destroy() | Unwraps store methods (restores originals) |

Monitor properties:

| Property | Description | |----------|-------------| | timeline | Raw timeline array (read-only) | | pathStats | Map<path, stats> of per-path metrics | | sessionId | Unique session identifier |

mountOverlay(monitor, container)

Injects a floating overlay panel into the DOM. Returns an unmount() function.

Features:

  • Real-time summary (sets/sec, unique paths, active subs)
  • Hot paths table sorted by set count with frequency bars
  • Hot listeners table sorted by fire count
  • Recent events timeline
  • Draggable, collapsible
  • Download JSON button
  • Reset button

Report Structure

{
  "sessionId": "a1b2c3d4",
  "elapsedMs": 12345.67,
  "totalEvents": 1024,
  "dropped": 0,
  "summary": {
    "totalSets": 500,
    "totalGets": 0,
    "totalFires": 1200,
    "uniquePaths": 15,
    "totalSubscribes": 8,
    "totalUnsubscribes": 2,
    "activeSubscribers": 6,
    "setsPerSec": 40.5
  },
  "batches": {
    "count": 10,
    "totalPaths": 45,
    "totalCoalesced": 12
  },
  "hotPaths": [
    { "path": "count", "sets": 100, "fires": 200, "avgSetMs": 0.012, "peakSetMs": 0.15 }
  ],
  "hotListeners": [
    { "path": "count", "fires": 200, "firesPerSec": 16.2 }
  ],
  "activeSubs": [
    { "id": "x1y2z3", "path": "count", "ts": 123.45 }
  ],
  "timeline": [
    { "type": "set", "path": "count", "dur": 0.012, "ts": 100.5, "_seq": 0 }
  ]
}

Architecture

Your App
  │
  ▼
store.set('x', 1)  ──►  perfSet()  ──►  originalSet()
                          │                    │
                          ▼                    ▼
                     record event         write + notify
                     update stats
  • Prepend pattern: wraps methods, delegates to originals
  • Ring buffer: bounded memory, drops oldest events
  • No core changes: works with any @uistate/core ≥ 5.0.0
  • Overlay at ~2 fps: minimal render overhead

Use Cases

  • Hot path detection: Find which paths are set most frequently
  • Slow set() diagnosis: Identify paths with high per-set latency
  • Subscriber audit: See which paths have listeners and how often they fire
  • Batch efficiency: Check if batches are coalescing writes effectively
  • Post-hoc analysis: Download JSON for post-hoc analysis

License

MIT — Copyright (c) 2026 Ajdin Imsirovic