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

@casoon/astro-webvitals

v0.4.10

Published

A lightweight Web Vitals monitoring component for Astro with debug overlay and analytics support

Readme

@casoon/astro-webvitals

Lightweight Real User Monitoring (RUM) for Astro. It measures the official Web Vitals in the browser, optionally sends batched reports to an endpoint, and includes a development-only debug overlay.

Website and documentation: casoon.github.io/astro-webvitals

Supports Astro v4–v7.

What it measures

  • Core Web Vitals: LCP, CLS, INP
  • Supporting metrics: FCP, TTFB
  • Navigation timings: DNS, TCP, DOM, LOAD
  • Optional Long Tasks (50ms or longer)
  • Optional diagnostic attribution for LCP, CLS and INP

The production path does not initialize the overlay, console capture, SEO inspection, or accessibility heuristic.

Install

pnpm add @casoon/astro-webvitals

Use

Add the component once to a shared layout, immediately before </body>.

---
import { WebVitals } from '@casoon/astro-webvitals';
---

<WebVitals endpoint="/api/analytics/vitals" sampleRate={0.1} />

Local dashboard

The optional dashboard is a static Astro route backed only by this browser's localStorage; it needs neither Cloudflare nor a database. It is useful for development and QA, not for team-wide production analytics.

// astro.config.mjs
import { defineConfig } from 'astro/config';
import { webVitalsDashboard } from '@casoon/astro-webvitals/integration';

export default defineConfig({
  integrations: [webVitalsDashboard()],
});
<WebVitals endpoint="/api/analytics/vitals" dashboard />

Open /__web-vitals. It shows the latest metric per route from this browser and can clear that local history. Run sitemap pass opens every page listed in /sitemap.xml in the current tab, waits briefly for each page to settle, and returns to the dashboard with local QA measurements. Alongside the metrics it shows browser-visible page checks for title, description, canonical, language, H1, Open Graph, skip link, alt attributes, link text, form labels and valid JSON-LD. It deliberately bypasses normal sampling for that explicitly started pass, while consent and Do Not Track still apply. This is a local QA complement to a build-time audit, not representative field data. Use webVitalsDashboard({ route: '/internal/web-vitals', enabled: process.env.NODE_ENV !== 'production' }) to change or disable the injected route.

For local diagnosis:

<WebVitals debug={import.meta.env.DEV} />

Reporting payload

Metrics are sent as a batch. id identifies one metric instance; aggregate delta values with the same id rather than treating repeated values as separate visits.

{
  metrics: [{
    name: 'LCP',
    value: 1840,
    delta: 1840,
    id: 'v4-…',
    rating: 'good',
    navigationType: 'navigate',
    timestamp: 1765900000000,
    attribution: { target: 'main > img.hero' } // only when enabled
  }],
  sessionId: 'session_…',
  userId: 'optional-user-id',
  timestamp: 1765900000100,
  url: 'https://example.com/',
  userAgent: '…'
}

The client flushes when a page becomes hidden and uses sendBeacon when possible. Custom request headers require fetch instead.

Options

| Prop | Default | Description | | --- | --- | --- | | debug | false | Development overlay, SEO inspection and console viewer. | | endpoint | — | Same-origin or CORS-enabled reporting endpoint. | | sampleRate | 1 | Fraction from 0 to 1; clamped at runtime. | | batchReporting / batchInterval | true / 5000 | Reporting batch behavior. | | maxBatchSize | 10 | Maximum entries before a batch flushes. | | attribution | false | Add privacy-safe diagnostic context to vital reports. | | trackLongTasks | false | Report supported Long Task entries. | | trackSoftNavigations | false | Include experimental browser-detected soft navigations. | | retryFailedMetrics | false | Store up to 50 failed entries in localStorage for a later retry. | | consent | true | Explicit collection gate. false prevents initialization. | | dashboard | false | Store the last 200 metrics in browser-local storage for the optional dashboard. | | respectDnt | false | Prevent initialization when navigator.doNotTrack === '1'. | | checkAccessibility | debug | Run the small, development-only accessibility heuristic. | | highlightAccessibility | false | Highlight heuristic findings. | | consoleDock | false | Show a development console dock. | | position | bottom-right | Desktop overlay position. |

performanceBudget changes debug-overlay indicators only. extendedMetrics exposes browser memory/network information in that overlay when supported. smartDetection is retained for compatibility but currently has no runtime effect.

Browser events

Every reported metric is also emitted locally. This is useful for analytics integrations that should not use an HTTP endpoint.

window.addEventListener('webvitals:metric', (event) => {
  const metric = (event as CustomEvent).detail;
  console.log(metric.name, metric.value, metric.rating);
});

Privacy and security

Works with Astro security.csp (no 'unsafe-inline' needed): the component passes its configuration as inert JSON (<script type="application/json">) and all code runs from the bundled module script, which Astro serves from your own origin. The debug overlay and console dock use no inline event handlers.

Use consent or respectDnt where required. Do not put secrets in headers: Astro serializes component props into the browser, so such values are public. Prefer a same-origin endpoint protected by normal session cookies.

The optional retry queue and attribution data should be enabled only after reviewing your privacy requirements.

Development

pnpm run type-check
pnpm run check
pnpm pack

License

MIT © CASOON