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

ts-common-lib

v0.0.5

Published

TypeScript common combining type utilities, validation patterns, and testing infrastructure

Readme

TypeScript common

A comprehensive TypeScript common combining type utilities, validation patterns, and testing infrastructure. This package aggregates reusable mapped types, validation schemas, and driver patterns to avoid re-writing them across different projects.

Features

  • Type Utilities: Advanced TypeScript type utilities for objects, tuples, functions, classes, and operands
  • Validation Patterns: Schema validation using ArkType with driver pattern support
  • Testing Infrastructure: Vitest configuration with coverage reporting

Performance & profiling (perf/)

The perf/ folder provides reusable performance testing and profiling for Node/TypeScript projects. Use it from any repo by depending on the common and the perf export (e.g. "ts-common-lib": "file:../../ts-common-lib" and import … from 'ts-common-lib/perf').

  • No build: Exports point to TypeScript source (.ts). Consumers (e.g. gateway) run with tsx and import ts-common-lib/perf; no dist/ or compiled output.
  • API: Import runScenarios, parseArgs, reporter helpers, and types from ts-common-lib/perf. The package is client-agnostic: ScenarioContext is generic (Record<string, unknown>). Your project registers its own client (e.g. REST, gRPC) and context shape; scenarios use that client and typed context.
  • Profiling: Consumer runs the .ts scripts under perf/profiling/ via tsx (e.g. a perf-profiling wrapper or direct tsx path/to/analyze.ts). Use --port=NNN or --service=name with env PERF_INSPECTOR_PORTS.
  • Layout: Sources under perf/ (e.g. perf/performance/, perf/profiling/, perf/hooks.ts). No perf/package.json, no perf/tsconfig.json, no perf/dist. Profiling scripts are grouped under perf/profiling/: common/ (shared CLI args), heap/ (snapshot, analyze, diff, allocation-sampling, baseline, snapshot-signal, memory-over-time, utils), cpu/ (profile, analyze, flamegraph, utils); at root: event-loop-delay.ts, gc-trace.ts. Names avoid redundant prefix (e.g. heap/diff.ts not heap/heap-diff.ts per CODING_STANDARDS). Run via npm scripts or tsx perf/profiling/<group>/<script>.ts.
  • Why exports in package.json: Node needs the subpath mapping so that import … from 'ts-common-lib/perf' resolves; baseUrl in tsconfig only applies to in-repo resolution. Consumers that run the profiling scripts (CDP/WebSocket) need ws in their own dependencies.
  • Hooks: perf/hooks.ts exposes a generic layer over perf_hooks: markStart/markEnd, measureAsync, measureEventLoopDelay, createMeasureObserver. Use in tests or microservices to measure spans and event loop lag. See test/perf.spec.ts for a full demo (hooks + runScenarios + MetricsCollector).
  • Single CLI: All commands go through perf/cli.ts. Run npm run perf -- <command> [args...] (e.g. perf -- flamegraph file.cpuprofile, perf -- heap --service=auth). Commands: demo:run | capture:cpu | capture:heap | capture:mem | capture:allocation | cpuprofile | heap | memory-over-time | allocation | event-loop-delay | baseline-heap | analyze | analyze-heap | heap-diff | flamegraph | gc-trace | heap-signal.
  • Real demo capture: Same expensive + leak cases in perf/demo-run.ts. Terminal A npm run perf -- demo:run; Terminal B npm run perf -- capture:cpu (or capture:heap, capture:mem, capture:allocation). Output → perf/fixtures/ (git/npm ignored). Then npm run perf -- analyze <file.cpuprofile> or perf -- analyze-heap <file.heapsnapshot>.
  • Test all commands: Run npm run perf:test-all (implemented in perf/test-all.ts, cross-platform Windows + Linux). It starts the demo, captures CPU/heap/memory/allocation to perf/fixtures/, then runs analyze, analyze-heap, flamegraph, heap-diff, gc-trace, heap-signal, event-loop-delay, and baseline-heap. You can also run analyze/flamegraph/analyze-heap/heap-diff on existing fixture files without the demo.

Profiling tools (CPU, memory, and beyond)

Beyond CPU profiling, other dimensions help explain slowdowns, OOMs, and odd behaviour. Summary of what the perf scripts support and when to use them:

| Tool | What it shows | Typical use | |------|----------------|-------------| | CPU profile (.cpuprofile) | Where CPU time is spent (self-time per function) | Capture during load; analyse with perf-analyze path/to/file.cpuprofile or Chrome DevTools → Performance → Load profile. | | Flamegraph (SVG) | Same data as CPU profile, visual bars | perf-flamegraph path/to/file.cpuprofile [--top=N] [--out=flame.svg]. Share or embed the SVG. | | Heap snapshot (.heapsnapshot) | Who holds memory (object graph, retainers) | Capture via inspector script or Node --heapsnapshot-signal=SIGUSR2 + perf-heap-signal --pid=NNN. Analyse: perf-analyze-heap path/to/file.heapsnapshot [--top=25]. | | Heap diff | What grew between two snapshots (leak check) | Take two snapshots (before/after load). perf-heap-diff before.heapsnapshot after.heapsnapshot [--top=20]. | | Memory over time | heapUsed / rss sampled during a run | perf-memory-over-time [--interval=5] [--duration=120]. Optionally --out=csv --out-file=.... Run stress in another terminal to see heap under load. | | Allocation sampling | Who allocates (not just who holds) | perf-allocation [--duration=30]. Run load during capture. Open JSON in Chrome Memory or parse for top allocators. | | Event loop delay | Lag between scheduled and actual run of setImmediate | perf-event-loop-delay [--duration=20] [--samples=50]. High p95/p99 → event loop blocked. | | GC trace | GC events (Scavenge, Mark-sweep) over time | perf-gc-trace --run="node app.js" [--duration=30] [--out=gc-summary.txt]. Correlate P99 spikes with GC. | | Heap snapshot on signal | Capture heap in prod without inspector | Target: node --heapsnapshot-signal=SIGUSR2 app.js. Trigger: perf-heap-signal --pid=NNN. Snapshot written by Node in target cwd. | | Baseline heap | CI regression: fail if heap exceeds baseline | perf-baseline-heap [--duration=15] [--baseline=BYTES] [--margin=1.2] [--out=baseline.txt]. Or set PERF_HEAP_BASELINE_BYTES. |

Memory / heap — when and how

  • Heap snapshot: Use when RSS or heap grows over time (possible leak), OOM crashes, or you want to see what’s retaining memory. Capture via script (inspector + CDP HeapProfiler.takeHeapSnapshot), Chrome DevTools, or Node --heapsnapshot-signal=SIGUSR2 + kill -SIGUSR2 <pid>. Analyse in Chrome → Memory → Load, or use perf-analyze-heap for a text summary.
  • Memory over time: Use process.memoryUsage() (or the script) to confirm “heap is growing” before taking snapshots.
  • Allocation sampling: Use perf-allocation (CDP) or Chrome DevTools → Memory → “Allocation instrumentation on timeline” or “Allocation sampling”. Use when you want to reduce allocations (lower GC or improve latency), not necessarily to find a leak.

Event loop / async

When latency is high and CPU profile shows a lot of “idle” or “(program)”, suspect I/O or event loop lag. Measure event loop delay (time between when a timer/tick was scheduled and when it ran). Options: perf_hooks, a small script with setTimeout/setImmediate, or tools like Clinic.js (clinic doctor). High delay → too much sync work per tick or slow I/O; then use CPU profile for sync work or DB/HTTP metrics for I/O.

Other dimensions

| Dimension | When to use | How (short) | |-----------|-------------|-------------| | DB / driver | Queries slow or pool saturated | Slow query log, driver metrics (pool size, queue). Add timing in resolvers or use APM. | | Redis | Cache/session latency | Redis INFO, LATENCY, client metrics. | | Network | Downstream HTTP or external APIs slow | HTTP client metrics, tracing (e.g. OpenTelemetry). | | Garbage collection | GC pauses visible in latency (P99 spikes) | Node --trace-gc or v8 flags; CPU profile shows “(garbage collector)”. Reduce allocations in hot paths if GC % is high. |

Quick decision table

| Symptom | First step | Then | |---------|------------|------| | High CPU, slow requests | CPU profile | Optimise hot functions; consider parse cache, projection. | | RSS/heap grows; OOM or suspicion of leak | Heap snapshot (before/after or over time) | Compare snapshots; find retainers; fix leaks or cap caches. | | High latency but CPU mostly idle | Event loop delay + DB/Redis latency | Find I/O or sync bottleneck; tune pool, indexes, or move work off the loop. | | P99 spikes, GC high in CPU profile | Allocation profile or trace-gc | Reduce allocations in hot paths; reuse objects. | | “Who allocates the most?” | Allocation sampling | DevTools or Clinic.js; then refactor hot allocators. |

References