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

@socketo/cli

v0.0.1

Published

Local Pusher-compatible WebSocket server for development

Readme

@socketo/cli

Local Pusher-compatible WebSocket server. Drop-in replacement for Pusher Channels during development — same protocol, zero config, no API key needed.

Built on Miniflare and Cloudflare Durable Objects, using the WebSocket Standard API for persistent in-memory state.

npx @socketo/cli start

Server listens at ws://localhost:8787.

Usage

npx @socketo/cli <command> [options]

Commands:
  start [options]              Start the local Pusher-compatible server
  subscribe <channel>          Subscribe to a channel and watch live events
  trigger <ch> <event> [data]  Trigger an event on a channel
  info                         Show server status and active channels
  generate                     Generate client/server code with prefilled keys
  help                         Show this help message

Start Options:
  -p, --port <port>            Port (default: 8787)
  --webhook-url <url>          Webhook URL for server-side callbacks
  --webhook-secret <secret>    HMAC secret for webhook signatures
  --app-secret <secret>        Secret for auth signature validation

Client SDK

import PusherJS from 'pusher-js'

const pusher = new Pusher('local', {
  wsHost: 'localhost',
  wsPort: 8787,
  forceTLS: false,
  enabledTransports: ['ws'],
  cluster: 'local',
})

Server SDK

import Pusher from 'pusher'

const server = new Pusher({
  appId: 'local',
  key: 'local',
  secret: 'local',
  host: 'localhost:8787',
  useTLS: false,
})

server.trigger('my-channel', 'my-event', { hello: 'world' })

CLI Commands

socketo subscribe <channel>

Subscribe to a channel and watch events in real-time:

socketo subscribe my-channel
socketo subscribe presence-chat --user-id alice

socketo trigger <channel> <event> [data]

Trigger events from the terminal:

socketo trigger my-channel my-event '{"hello":"world"}'

socketo info

Show server status and active channels:

socketo info

socketo generate

Generate client/server boilerplate code with prefilled keys:

socketo generate

Supported

WebSocket Protocol

  • pusher:connection_established handshake (with socket_id and activity_timeout: 120)
  • Subscribe / unsubscribe (public, private, presence, encrypted)
  • Client events (client-*)
  • Ping / pong
  • User signin (pusher:signin / pusher:signin_success)
  • Auth signature validation (when --app-secret is set)

Presence Channels

  • channel_data with user_id and user_info
  • pusher_internal:subscription_succeeded with member list (ids, hash, count)
  • member_added / member_removed events (with user_id in client events)

REST API

| Method | Path | Description | |---|---|---| | POST | /apps/local/events | Trigger events (single or multi-channel) | | POST | /apps/local/batch_events | Batch trigger (max 10 events) | | POST | /apps/local/auth | Auth endpoint for private/presence channels | | GET | /apps/local/channels | List channels | | GET | /apps/local/channels/{name} | Channel info | | GET | /apps/local/channels/{name}/users | Presence users | | POST | /apps/local/users/{id}/terminate_connections | Disconnect user |

Query params: ?filter_by_prefix= and ?info=user_count,subscription_count.

Webhooks

POST to your URL when channels are occupied/vacated, members join/leave, or client events fire. Payload matches Pusher's webhook format with X-Pusher-Key and X-Pusher-Signature (HMAC-SHA256) headers.

State

Connection state survives indefinitely (no hibernation). Channels, members, and user data persist across requests.

CORS

All HTTP endpoints return Access-Control-Allow-Origin: *.

Tests

37 integration tests covering the full Pusher Channels protocol: connection, channels, presence, events, auth, REST API, webhooks, and error handling.

bun test

Not Supported

  • End-to-end encryption (encrypted channels are routed but not encrypted)
  • Cache channels
  • TLS / WSS
  • body_md5 validation
  • Watchlist
  • Server-initiated ping (client-initiated pong is supported)