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

@pionne/web

v0.3.6

Published

Error monitoring SDK for the browser — Pionne. Auto-captures uncaught errors and unhandled rejections, ships client context (UA, viewport, locale), tracks Release Health (crash-free user rate), and exposes a feedback API.

Downloads

1,093

Readme

@pionne/web

Error monitoring SDK for the browser — by Pionne.

Auto-captures uncaught errors and unhandled promise rejections, ships rich client context (UA, OS, viewport, locale, URL), and survives page unloads via navigator.sendBeacon. ~3 KB gzipped, zero dependencies, no source maps required.

Works in any browser app — plain JS, React, Vue, Svelte, Angular, Next.js, Astro, etc.

🎫 Get your token

Pionne is mobile-first: you sign up, create projects, and watch your error feed from the Pionne mobile app, not a web dashboard.

  1. Download the app:
  2. Create your account (30 days free, no card required)
  3. + New project → pick Web → copy the token displayed (pio_live_…)
  4. Paste it into Pionne.init({ token }) below

⚠️ The token is only shown once at project creation — store it in an env var (VITE_PIONNE_TOKEN, NEXT_PUBLIC_PIONNE_TOKEN, etc.) and never commit it.

Install

npm install @pionne/web

Usage

React / Next.js / Vite

// main.tsx (or _app.tsx for Next, root.ts for Remix…)
import { Pionne } from '@pionne/web';

Pionne.init({
  token: 'pio_live_xxx',
  release: '1.0.0', // optional
  // environment auto-detected (localhost → development, else production)
});

That's it. JS errors and unhandled promise rejections are now reported automatically.

Manual capture

try {
  doRiskyThing();
} catch (err) {
  Pionne.captureException(err, { tags: { feature: 'checkout' } });
}

Pionne.captureMessage('user reached empty state', { level: 'info' });

User identity (anonymous)

Pionne.setUser('u_42'); // appears on every event afterward
Pionne.setUser(null);    // forget

Tags

Pionne.setTags({ tier: 'pro', region: 'eu' });

Opt-out

Pionne.setEnabled(false);

Profiling — preview (coming soon)

Continuous-ish CPU profiling is shipped on @pionne/[email protected] (Hermes sampler) and is on the roadmap for @pionne/web next. The browser implementation will use Performance.profile() (Chrome only, behind a flag in Firefox/Safari) and fall back to Performance.measure()-based manual spans where the sampler isn't available.

The API will mirror RN exactly so you can reuse the same wrappers across platforms:

// Coming in @pionne/web ~v0.4.0
await Pionne.profile('CheckoutFlow', async () => {
  await fetchCart();
  await submitOrder();
}, { route: '/checkout' });

Same backend (POST /api/profiles), same retention model (raw 7 d, aggregates 90 d), same flame graph view in the mobile dashboard.

If you need profiling today in a browser, you can post your own samples to the endpoint directly — the JSON shape is documented at pionne.agkgcreations.fr/profiling/intro.

Bundle ID pinning — N/A on Web

The "Bundle ID" anti-token-theft check on Pionne projects is mobile only (iOS/Android/RN/Flutter). On the web, your token is shipped in the bundled JS and trivially extractable from the browser — bundle pinning can't help. The field is hidden in the mobile dashboard for Web projects; don't set it manually via the API — the SDK does not send a top-level app_id, so a non-null bundle_id would 403 every event. To limit abuse: regenerate the token (24 h grace period) if you suspect a leak, and rely on the per-token rate limit server-side. Use tags for deployment/tenant differentiation. See the Bundle ID Pinning docs.

Geography (opt-in)

Approximate visitor location (city, region, country) attached to every event, just like Sentry. Off by default for privacy — flip sendGeography to enable:

Pionne.init({
  token: 'pio_live_xxx',
  sendGeography: true,
});

Resolved once at startup via a free IP→geo lookup (ipapi.co/json by default), with a 4 s timeout. If the lookup fails the SDK silently keeps shipping events without geo. Override the endpoint via geographyEndpoint if you have your own.

Options

| Option | Type | Default | | ---------------------------- | -------------------------- | ------------------------- | | token | string (required) | — | | endpoint | string | Pionne production | | release | string | unset | | environment | string | localhost-detected | | enabled | boolean | true | | captureUncaughtErrors | boolean | true | | captureUnhandledRejections | boolean | true | | autoContext | boolean | true | | userIdAnon | string | unset | | tags | Record<string, string> | unset | | maxStackFrames | number | 50 | | beforeSend | (event) => event \| null | unset (drop if null) | | sendGeography | boolean | false | | geographyEndpoint | string | https://ipapi.co/json/ | | releaseHealth | boolean | true | | maxEventsPerSecond | number | 10 |

Notes

  • maxEventsPerSecond — token-bucket client. Au-delà, les events sont droppés silencieusement. Protège contre les setInterval qui throw en boucle. 0 désactive (déconseillé).
  • releaseHealth — ouvre une session à init() pour calculer le crash-free user rate. Désactivable.
  • sendGeography — opt-in : attache contexts.geo (city/region/country/country_code) résolu IP-side. Pas de geolocation API, pas de permission.

Rate limit serveur

Indépendamment du maxEventsPerSecond client, l'API Pionne applique un rate-limit par token sur tous les endpoints publics. Au-delà → HTTP 429 avec un header Retry-After. Empêche un token leaké de drainer ton quota mensuel. Voir doc rate limits.

License

MIT