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

@rivium/push-web

v0.1.1

Published

Web Push SDK for browsers - Firebase alternative that works everywhere

Downloads

86

Readme

RiviumPush Web SDK

Real-time push notifications for browsers. No Firebase dependency.

Features

  • Real-time push notifications via WebSocket
  • Web Push (VAPID) for background notifications when browser is closed
  • Rich notifications (images, action buttons, badges, deep links)
  • Topic subscriptions
  • Auto-reconnection with exponential backoff
  • Network and visibility state monitoring
  • Badge management (Badge API + favicon fallback)
  • Localization support
  • Analytics tracking
  • TypeScript support
  • Works with any framework (React, Vue, Angular, vanilla JS)

Installation

NPM

npm install @rivium/push-web

CDN (UMD)

<script src="https://unpkg.com/@rivium/push-web/dist/index.umd.js"></script>

CDN (ES Module)

<script type="module">
  import RiviumPush from 'https://unpkg.com/@rivium/push-web/dist/index.esm.js';
</script>

Service Worker Setup

Copy the service worker file to your public directory:

# NPM
cp node_modules/@rivium/push-web/service-worker.js public/rivium-push-sw.js

# CDN
curl -o public/rivium-push-sw.js https://unpkg.com/@rivium/push-web/service-worker.js

Quick Start

import RiviumPush from '@rivium/push-web';

// Initialize
const riviumPush = new RiviumPush({
  apiKey: 'rv_live_your_api_key',  // Get from Rivium Console
});

// Set up callbacks
riviumPush.onMessage((message) => {
  console.log('Title:', message.title);
  console.log('Body:', message.body);
  console.log('Data:', message.data);
});

riviumPush.onConnectionState((state) => {
  console.log('Connection:', state); // 'connected' | 'disconnected' | 'connecting'
});

riviumPush.onRegistered((deviceId) => {
  console.log('Device ID:', deviceId);
});

// Register device (requests notification permission automatically)
const deviceId = await riviumPush.register({ userId: 'user_123' });

Configuration

const riviumPush = new RiviumPush({
  apiKey: 'rv_live_...',                    // Required - from Rivium Console
  serviceWorkerPath: '/rivium-push-sw.js',  // Optional - service worker path
  autoRegisterServiceWorker: true,          // Optional - auto register SW (default: true)
  mqttQos: 1,                              // Optional - MQTT QoS level (default: 1)
  maxReconnectAttempts: 10,                 // Optional - max reconnect attempts (default: 10)
  logLevel: RiviumPushLogLevel.ERROR,       // Optional - log level
});

Callbacks

All event handlers return an unsubscribe function.

// Receive messages (foreground)
const unsub = riviumPush.onMessage((message) => {
  console.log(message.title, message.body);
});

// Connection state
riviumPush.onConnectionState((state) => {
  // 'connecting' | 'connected' | 'disconnected' | 'error'
});

// Registration complete
riviumPush.onRegistered((deviceId) => {});

// Background notification click
riviumPush.onNotificationClick((message, action) => {
  if (message.deepLink) {
    window.location.href = message.deepLink;
  }
});

// Action button click
riviumPush.onActionClicked((actionId, message) => {
  console.log('Action:', actionId);
});

// Errors
riviumPush.onError((error) => {});
riviumPush.onDetailedError((error) => {
  console.log('Code:', error.code, 'Message:', error.message);
});

// Reconnection
riviumPush.onReconnecting((state) => {
  console.log('Attempt:', state.retryAttempt, 'Next in:', state.nextRetryMs, 'ms');
});

// Network state
riviumPush.onNetworkState((state) => {
  console.log('Online:', state.isAvailable, 'Type:', state.networkType);
});

// App visibility
riviumPush.onAppState((state) => {
  console.log('Visible:', state.isVisible);
});

// Clean up
unsub();

Topics

await riviumPush.subscribeTopic('news');
await riviumPush.subscribeTopic('promotions');
await riviumPush.unsubscribeTopic('promotions');

User Management

// Set user ID after login
await riviumPush.setUserId('user_123');

// Clear user ID on logout
riviumPush.clearUserId();

// Register with user ID
await riviumPush.register({ userId: 'user_123' });

Badge Management

riviumPush.setBadgeCount(5);
riviumPush.clearBadge();
const count = riviumPush.getBadgeCount();

Analytics

riviumPush.setAnalyticsHandler((event, properties) => {
  // Send to your analytics service
  analytics.track(`rivium_push_${event}`, properties);
});

riviumPush.disableAnalytics();

Log Levels

import { RiviumPushLogLevel } from '@rivium/push-web';

riviumPush.setLogLevel(RiviumPushLogLevel.DEBUG);   // Development
riviumPush.setLogLevel(RiviumPushLogLevel.ERROR);   // Production

// Available: NONE, ERROR, WARNING, INFO, DEBUG, VERBOSE

Utilities

const connected = riviumPush.isConnected();
const deviceId = riviumPush.getDeviceId();
const network = riviumPush.getNetworkState();
const appState = riviumPush.getAppState();
const initialMessage = riviumPush.getInitialMessage();

// Static methods
RiviumPush.isSupported();
RiviumPush.getPermissionStatus();

// Unregister
await riviumPush.unregister();

CDN Usage (HTML)

<!DOCTYPE html>
<html>
<head>
  <title>My App</title>
</head>
<body>
  <script src="https://unpkg.com/@rivium/push-web/dist/index.umd.js"></script>
  <script>
    const riviumPush = new RiviumPushWeb.default({
      apiKey: 'rv_live_your_api_key',
    });

    riviumPush.onMessage(function(message) {
      console.log('Received:', message.title);
    });

    riviumPush.onConnectionState(function(state) {
      console.log('Connection:', state);
    });

    riviumPush.register().then(function(deviceId) {
      console.log('Registered:', deviceId);
    });
  </script>
</body>
</html>

Browser Support

  • Chrome 50+ (Desktop & Android)
  • Firefox 44+
  • Edge 17+
  • Safari 16+ (macOS only, iOS does not support Web Push)
  • Opera 37+

Requirements

  • HTTPS required (localhost works for development)
  • Service worker file must be in the public root directory

Example

See the web_example directory for a complete interactive demo with all features.

The Push SDK works independently without VoIP.

Links

License

MIT License - see LICENSE for details.