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

@sequentialos/zellous

v2.0.0

Published

Real-time collaboration and communication library with PTT, rooms, and file sharing

Readme

Zellous - Browser PTT Communication

A production-ready Push-to-Talk application with Opus codec, dynamic rooms, audio replay, and real-time multi-user support.

Quick Start

Local Development:

npm install
npm start
# Visit http://localhost:3000

Remote Server Deployment:

npm install
export PORT=3000
export HOST=0.0.0.0  # Listen on all interfaces
npm start
# Server now accessible from external domains

Development with hot reload:

npm run dev

Join a specific room:

http://localhost:3000?room=meeting
http://localhost:3000?room=team1

Important: For remote access (e.g., zellous.247420.xyz), ensure:

  1. Server is running with HOST=0.0.0.0 (automatic by default)
  2. Firewall allows inbound traffic on the PORT (default: 3000)
  3. For domains, set up reverse proxy (nginx) or use port 80/443
  4. See CLAUDE.md for nginx configuration example

Features

  • Push-to-Talk: Hold button to record and transmit
  • Opus Codec: 24kbps bitrate, 93.75% bandwidth reduction
  • Dynamic Rooms: URL-based rooms with complete isolation
  • Audio Replay: Replay last 50 messages with audio
  • Live Playback: Stream audio in real-time from other speakers
  • Auto Pause/Resume: Playback automatically pauses when you talk
  • Active Speakers: Real-time display of who's speaking
  • Message History: Timestamped communication log with replay buttons
  • Multi-user: Supports simultaneous speakers per room
  • Volume Control: Master volume slider (0-100%)
  • Hot Reload: Nodemon for development
  • Responsive: Desktop and mobile friendly

Architecture

Zellous uses a modular, scalable design:

Frontend (app.js - 373 lines)

Modules:

  • config - Constants
  • state - Centralized state object (18 properties including roomId)
  • audio - Opus encoding/decoding/playback/replay
  • message - Message routing (7 message types)
  • network - WebSocket communication with room injection
  • audioIO - Microphone/recording
  • ptt - Push-to-talk logic
  • ui_* - UI rendering and events

Backend (server.js - 93 lines)

Handler pattern:

handlers = {
  join_room: (client, msg) => { /* ... */ },
  audio_start: (client) => { /* ... */ },
  audio_chunk: (client, msg) => { /* ... */ },
  audio_end: (client) => { /* ... */ },
  set_username: (client, msg) => { /* ... */ }
}

Room-filtered broadcast efficiently distributes messages only to clients in the same room.

HTML (index.html - 68 lines)

Semantic HTML with inline CSS. No external dependencies.

State Management

Single centralized state object contains:

  • Audio context, microphone stream
  • Opus encoder/decoders per user
  • Audio buffers and sources per user
  • Active speakers set
  • Message history array (50 messages)
  • Audio history for replay
  • WebSocket connection
  • User ID, room ID, speaking state

Benefits:

  • Predictable data flow
  • Easy debugging
  • Simple reset capability
  • Clear dependencies

Message Protocol

Client → Server

{ type: 'join_room', roomId: 'lobby' }     // Join a room
{ type: 'audio_start' }                    // User started talking
{ type: 'audio_chunk', data: [...] }       // Audio data (Opus)
{ type: 'audio_end' }                      // User stopped talking
{ type: 'set_username', username: 'name' } // Update username

Server → Client

{ type: 'room_joined', roomId, currentUsers }     // Room join confirmed
{ type: 'speaker_joined', user, userId }          // User started talking
{ type: 'speaker_left', userId, user }            // User stopped talking
{ type: 'audio_data', userId, data }              // Audio chunk
{ type: 'user_joined', user, userId }             // User connected
{ type: 'user_left', userId }                     // User disconnected
{ type: 'connection_established', clientId }      // Connection confirmed

Audio Features

  • 48kHz sample rate for quality
  • Opus codec at 24kbps bitrate
  • WebCodecs API for native encoding/decoding
  • 93.75% bandwidth reduction (384kbps → 24kbps)
  • 4096 sample chunks for low latency
  • 100ms playback intervals for smooth audio
  • Per-user AudioDecoder for concurrent playback
  • Audio replay for last 50 messages

Extending Zellous

Add a Message Type

Server (server.js):

handlers.my_message = (client, msg) => {
  broadcast({ type: 'my_response', data: msg.data });
}

Client (app.js):

message.handlers.my_response = (msg) => {
  // Handle response
}

Add a UI Control

  1. Add element to HTML
  2. Add reference to ui object
  3. Create render function in ui_render
  4. Bind events in ui_events.setup()

Add Audio Effects

Add methods to audio module and call from playback loop.

Rooms Already Implemented!

Dynamic rooms work via URL query parameters:

http://localhost:3000?room=team1
http://localhost:3000?room=meeting

Complete isolation between rooms with zero configuration required.

Debug Console

Access all internals via window.zellousDebug:

window.zellousDebug.state       // Full application state
window.zellousDebug.audio       // Audio functions
window.zellousDebug.message     // Message handlers
window.zellousDebug.network     // Network functions
window.zellousDebug.ptt         // PTT controls
window.zellousDebug.config      // Configuration

Performance

  • Minimal dependencies: Express, WebSocket only
  • Event-driven: No polling
  • Audio buffering: Prevents stuttering
  • Opus codec: 93.75% bandwidth savings
  • Map-based storage: O(1) client lookups
  • Room filtering: O(1) per-client comparison

Browser Support

Full Support (WebCodecs API):

  • Chrome/Chromium 94+ (Opus encoder/decoder)
  • Edge 94+ (Opus encoder/decoder)
  • Opera 80+ (Opus encoder/decoder)

Partial Support:

  • Safari Technology Preview (AudioDecoder only)

Requirements:

  • Web Audio API
  • WebCodecs API (AudioEncoder, AudioDecoder)
  • MediaDevices API

Production Considerations

Already Implemented:

  • ✅ Multiple rooms/channels (URL-based, zero config)
  • ✅ Hot reload for development
  • ✅ Audio replay functionality

Ready for:

  • User authentication (add to message handlers)
  • Encryption (wrap network.send)
  • Database integration (replace broadcast)
  • Clustering (use Redis, socket.io)
  • Recording (add to audio.play callback)

See CLAUDE.md for detailed technical documentation.

Files

server.js         - Express + WebSocket server (93 lines)
app.js            - Frontend application (373 lines)
index.html        - UI markup and styles (68 lines)
package.json      - Dependencies (express, ws, nodemon)
nodemon.json      - Hot reload configuration (5 lines)
README.md         - Quick start and features
CLAUDE.md         - Technical reference
CHANGELOG.md      - Version history

License

MIT