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

@krizaka/push

v0.2.1

Published

Mobile push without an SDK: the Expo Push Service relays to FCM (Android) and APNs (iOS) from one HTTP call. Pure and dependency-free: batches by 100, never throws, reports the dead tokens to forget.

Readme

@krizaka/push

Mobile push without an SDK: the Expo Push Service relays to Firebase Cloud Messaging on Android and to the Apple Push Notification service on iOS, from one HTTP call and one kind of token (ExponentPushToken[…]). The FCM and APNs credentials live in the app's EAS project — never on your server.

npm install @krizaka/push

ESM only, Node ≥ 22, zero dependency: you pass fetch (the global one in production, a fake in tests).

Use

import { isExpoPushToken, sendExpoPush } from "@krizaka/push";

// When the phone registers: refuse anything that is not an Expo token before storing it.
if (!isExpoPushToken(token)) return badRequest();

// When something happens: one message per device, sent in batches of 100.
const outcome = await sendExpoPush(
  devices.map((d) => ({ to: d.token, title, body, data: { path: "/inbox/42" } })),
  { fetch, accessToken: process.env.PUSH_ACCESS_TOKEN },   // the token: only with "enhanced push security" on
);
await forgetTokens(outcome.deadTokens);                     // uninstalled app, revoked permission
if (outcome.errors.length) log.warn(outcome.errors[0]);

| Export | What | | :-- | :-- | | sendExpoPush(messages, { fetch, accessToken? }) | Sends in batches of EXPO_PUSH_BATCH (100); returns { sent, deadTokens, errors }. Never throws. Messages whose to is not an Expo token are dropped before any call. Defaults: sound: "default", channelId: "default" (create that Android channel in the app). | | isExpoPushToken(token) | Whether a string looks like an Expo push token. | | PushMessage, PushTicket, PushOutcome | The types. | | EXPO_PUSH_URL, EXPO_PUSH_BATCH | The endpoint and the batch size. |

The rules it carries

  • Best-effort. A push repeats what the app already shows (the bell, the inbox); it never decides anything. Write the fact first, push second.
  • Dead tokens are forgotten. DeviceNotRegistered tickets come back in deadTokens: delete them.
  • Data, not secrets. data is delivered to the device as is: a path to open, an id — never personal content you would not show on a lock screen.
  • Send from production only (or behind an explicit switch): local runs and CI should never call the service.

Switching to FCM HTTP v1 and APNs directly later changes this package only, not its callers.

How the Krizaka products use it

  • A video platform: a push for each notification an account allows (a new follower, a message, an auction outbid), sent after the notification is written, the dead tokens deleted from its push_devices table.
  • A dating app: "your batch is ready", a new intro, a message in an intro.

License

Apache-2.0 © Krizaka