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

@profullstack/residentalerts

v0.8.0

Published

resident.alerts: live 911 incidents near you on a map, push alerts for the places you care about, and the police and fire radio for your county. Free, with Premium for $4.99 once.

Readme

resident.alerts

Live 911 incidents near you on a map, push alerts for the places you care about, and the police and fire radio for your county. No account, no ads.

Free: the live map and list (24 h), radio, every kind of call, push alerts for 1 place within 3 miles. Premium, $4.99 once for life (CoinPay): up to 25 places, up to 50 miles each, 7 and 30 days of history. Premium is a key (ra_…), made at checkout and valid once the payment settles; the browser keeps it, and X-Premium-Key sends it to the API.

  • Web / PWA: https://resident.alerts (Moshpit DNS) or https://resident.alerts.pit.world
  • API: GET /api/v1/incidents?lat=&lon=&km=&hours=&kinds=&min_severity=, /api/v1/incidents/:id, /api/v1/radio?lat=&lon=, /api/v1/sources
  • CLI + TUI: bunx @profullstack/residentalerts near 47.61 -122.33, … watch 47.61 -122.33
  • MCP: claude mcp add residentalerts -- bunx @profullstack/residentalerts mcp

Accounts

Email sign-in with a one-time link (no password): /signin -> link (hashed, single use, 20 min, spent by a POST so mail scanners cannot) -> 180-day session cookie (writes only count with Sec-Fetch-Site: same-origin). An account holds Premium (bought while signed in, or a key attached on /account), synced alert places and the community name. Buying Premium and posting need an account; the map, radio and one alert place do not. Sign in with CoinPay (OAuth 2.1 code + PKCE S256, client cp_14548d98fe01a7ca13c42dd0, COINPAY_OAUTH_CLIENT_ID/SECRET): accounts link by CoinPay sub, never by email (CoinPay emails are unverified). A new CoinPay-only account keeps that email aside as unverified (not an admin, not on the mailing list) until it is confirmed with a one-time link from /account; confirming an email that already has an account merges the two. A signed-in email account can connect CoinPay from /account. ADMIN_EMAILS have Premium. Mail goes through Resend (RESEND_API_KEY, MAIL_FROM); GET /api/v1/admin/emails (x-admin-key) exports the opt-in list as CSV.

Credit codes and invites

Credit codes (@profullstack/redeem-credits): a code grants the unit premium; one with amount 1 is lifetime Premium, the same thing $4.99 buys. A signed-in person redeems it under "Have a code?" on /account (or POST /api/v1/redeem {"code"} with the session cookie). The credit is applied the way a purchase is: a settled $0 row in payments (chain credit-code) on the account, so Premium has one source of truth and moves with the account on a merge. Someone who already has Premium is refused before the code is spent. Mint one on the server (run the bin under bun; its node shebang fails as root):

cd /opt/resident.alerts
bun $(readlink -f node_modules/.bin/redeem-credits) mint --db "$DATABASE_PATH" \
  --unit premium --amount 1 --label "for Dan" [--max 10] [--expires 30d]
bun $(readlink -f node_modules/.bin/redeem-credits) list   --db "$DATABASE_PATH"
bun $(readlink -f node_modules/.bin/redeem-credits) revoke <codeId> --db "$DATABASE_PATH"

A grant --unit premium --amount 1 --user <account id> works too: it switches on the next time that person opens /account.

Invites (@profullstack/affiliates): three single-use links per account at /invites (GET/POST /api/v1/invites). A link lands on /invite/<code> (/i/ is an incident page), rides in a 7-day cookie, and is spent when that browser makes a new account (email link or CoinPay). Premium is lifetime-only and there is nothing smaller to give, so an invite gives neither person anything beyond the invite: we only remember who brought whom. Every account also has an affiliate link (/?ref=<code>), remembered first-touch for 30 days and credited to new accounts.

Webhooks

Customer webhooks via @profullstack/webhooks: an account adds endpoints on /account#webhooks, with residentalerts webhook add <url>, MCP create_webhook, or POST /api/v1/webhooks. The API takes an account API key (Authorization: Bearer rak_…, made on /account, stored hashed, one per account), a Premium key that belongs to an account (X-Premium-Key), or the signed-in session from our own pages; anything else is 401. Bodies are CloudEvents, signed per Standard Webhooks, queued in the app's SQLite (webhook_endpoints, webhook_deliveries) and retried for about three days; URLs must be https to public addresses.

| Event | When | Owner | | --- | --- | --- | | alert.issued | a new incident (or a fire that grew into it) in a place saved to the account | the account whose places it is in | | alert.updated / alert.ended | an incident the account was sent changed / stopped being listed | same | | premium.activated | the account's Premium switched on (payment settled, or a credit code) | the account |

Devices stay anonymous push subscriptions, so they own no webhooks. A payload carries the incident as the public map shows it plus which of the owner's places it concerns: never a resident's name, token or media, nor anyone else's places. Same 30-minute freshness rule as push, at most 200 events an account an hour; deleting an account deletes its webhooks, and merging accounts moves them.

Community

Residents (rt_ token + name, tied to an account): comments on every incident, an area chat per ~40 km geohash cell, residents' own reports (unverified; push only after two other residents confirm), photos and videos. Photos are re-encoded in the browser (EXIF/GPS gone), MP4/MOV udta/meta boxes are blanked on the server, files are capped (10 MB photo, 25 MB video, 30/day, MEDIA_MAX_GB total, oldest first) and served sandboxed with ranges. Three flags hide anything; ADMIN_KEY removes and bans (resident + network).

Where the data comes from

Public feeds agencies publish themselves, read every few minutes on the server (see src/cities.ts and /coverage):

| Feed | Area | Notes | | --- | --- | --- | | Seattle Fire real-time 911 | Seattle, WA | Socrata kzjm-xkqj | | SFPD dispatched calls | San Francisco, CA | Socrata gnap-fj3t (~15 min behind) | | Austin Fire + Austin traffic/police | Austin, TX | Socrata wpu4-x69d, dx9v-zd7x | | Tulsa Fire dispatch | Tulsa, OK | JSON | | Monroe County 911 | Rochester, NY | RSS with geo | | Houston Fire + Police active incidents | Houston, TX | HTML table, geocoded | | San Diego Fire-Rescue dispatch | San Diego, CA | JSON, geocoded | | Orlando Police active calls | Orlando, FL | XML, geocoded | | NWS warnings (with polygons) | US | api.weather.gov | | USGS earthquakes M2.5+ | world | GeoJSON | | Wildfires: NIFC WFIGS points + perimeters, CAL FIRE incidents | US | WFIGS ArcGIS (perimeters drawn, merged with CAL FIRE by name and distance) | | Evacuation zones (orders, warnings, advisories) | US | Genasys Protect public WFS (zonehavenv2:evacuation_zone) | | California Highway Patrol CAD | all of California | ASP.NET page, all 25 centers, Details postback for lat/lon |

Feeds without coordinates are placed by the US Census geocoder (block addresses) or by intersecting the two streets' OpenStreetMap lines (Nominatim, one request a second, every answer cached in SQLite).

Radio: point -> county (FCC Census Area API) -> Broadcastify's county page -> live scanner feeds; ▶ opens Broadcastify's own mini player in a popup (their player sends frame-ancestors 'none' and streams use per-listener tokens, so it cannot play inside another site). Live 911 caller recordings are not published anywhere in the US; what apps call "911 audio" is dispatch radio. OpenMHz (trunked radio clips) blocks datacenter IPs and cross-origin browser requests behind a Cloudflare challenge, so it can't be embedded.

Wildfire (Watch Duty-style): fires, evacuation zones and NWS warnings are live sources: each read is the agency's whole current list, so an incident stays on the map for as long as it is listed (not just inside the hours window) and ends when it drops off. A device can follow a fire (POST /api/v1/devices/follow) and gets a push when its acres, containment or status change and when it is out; a fire whose perimeter grows to within an alert place's radius alerts that place once. The 🛰 button draws VIIRS satellite hotspots (Esri Living Atlas layer fed by NASA FIRMS, no key; FIRMS' own API needs one). Fires and evacuation zones show the wind, humidity and temperature from the nearest NWS station and the AQI from the nearest EPA AirNow monitor (hourly public files). Open-Meteo was skipped: its free tier is non-commercial only.

Map tiles: OpenStreetMap's standard tiles, darkened with a CSS filter.

Alerts

A device is its push subscription; places, kinds and minimum severity are stored next to it and nothing else. Only incidents new to us and reported in the last 30 minutes alert; a source's first read is silent; at most 20 pushes per device per hour, most serious first.

Run it

bun install
VAPID_PUBLIC_KEY=… VAPID_PRIVATE_KEY=… DATABASE_PATH=./ra.db bun src/server.ts   # :8806
bun test

Deploy (dev2): ssh root@dev2 'cd /opt/resident.alerts && git pull && ./bin/install.sh'.

MIT licensed.