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

@onurege3467/workspaces

v1.0.0

Published

A secure, feature-rich WebSocket client-server package with encryption, rooms, compression, heartbeat, and more.

Readme

@onurege3467/workspaces

🚀 Secure, feature-rich WebSocket client-server package for Node.js

npm version TypeScript Test Coverage

📖 Table of Contents

✨ Features

  • 🔒 End-to-End Encryption - Diffie-Hellman key exchange + AES-256-GCM with secure key derivation
  • 🏠 Room/Channel System - Organize clients into rooms for targeted messaging
  • 💓 Heartbeat/Ping-Pong - Keep connections alive and detect dead connections
  • 🔄 Exponential Backoff Reconnection - Smart reconnection strategy that adapts
  • 🗜️ Message Compression - Reduce bandwidth usage with gzip compression
  • 🛡️ Security - Token authentication, IP whitelist, CORS support, Rate limiting
  • Remote Code Execution - Secure sandboxed code execution with VM2
  • 🎯 TypeScript - Fully typed with excellent IntelliSense support
  • 98.1% Test Coverage - Comprehensive test suite with integration tests
  • 🚀 High Performance - 100 clients connect in ~224ms, broadcast in ~112ms

📦 Installation

npm install @onurege3467/workspaces ws

Note: ws is a peer dependency and must be installed separately.

🚀 Quick Start

Server

import { Server } from '@onurege3467/workspaces'

const server = new Server({
  port: 8080,
  token: 'your-secret-token',
  enableEncryption: true,
  enableRooms: true,
  enableHeartbeat: true,
  enableCompression: true,
  allowedOrigins: ['https://example.com'],
  enableRateLimit: true
})

server.listen(() => {
  console.log('Server running on port 8080')
})

// Broadcast to all clients
server.broadcast({ type: 'announcement', message: 'Welcome!' })

// Broadcast to a specific room
server.to('general').broadcast({ type: 'message', content: 'Hello general!' })

Client

import { Client } from '@onurege3467/workspaces'

const client = new Client({
  address: 'localhost:8080',
  token: 'your-secret-token',
  name: 'MyClient',
  enableEncryption: true,
  enableCompression: true,
  reconnectInterval: 5000,
  reconnectMaxInterval: 60000,
  reconnectBackoffFactor: 2,
  enableHeartbeat: true
})

client.on('open', () => {
  console.log('Connected!')
  client.send('Hello server!')
  client.join('general')
})

client.on('message', (message) => {
  console.log('Received:', message)
})

client.on('error', (error) => {
  console.error('Error:', error.message)
})

client.connect()

⚙️ Configuration

Server Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | port | number | required | Server port | | token | string | required | Authentication token | | enableEncryption | boolean | false | Enable end-to-end encryption | | enableRooms | boolean | false | Enable room/channel system | | enableHeartbeat | boolean | false | Enable heartbeat monitoring | | heartbeatInterval | number | 30000 | Heartbeat interval (ms) | | heartbeatTimeout | number | 5000 | Heartbeat timeout (ms) | | enableCompression | boolean | false | Enable message compression | | compressionThreshold | number | 1024 | Compression threshold (bytes) | | ipWhitelist | string[] | [] | Allowed IP addresses | | allowedOrigins | string[] | [] | CORS allowed origins | | allowCredentials | boolean | false | Allow CORS credentials | | maxConnections | number | 1000 | Maximum connections | | enableRateLimit | boolean | true | Enable rate limiting | | rateLimitMaxRequests | number | 100 | Max requests per window | | rateLimitWindowMs | number | 60000 | Rate limit window (ms) | | enableCodeExecution | boolean | false | DANGER: Enable remote code execution | | codeExecutionTimeout | number | 5000 | Code execution timeout (ms) | | codeExecutionMemoryLimit | number | 134217728 | Code execution memory limit (bytes) |

Client Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | address | string | required | Server address (host:port) | | token | string | required | Authentication token | | enableEncryption | boolean | false | Enable end-to-end encryption | | enableCompression | boolean | false | Enable message compression | | reconnectInterval | number | 5000 | Initial reconnection interval (ms) | | reconnectMaxInterval | number | 60000 | Max reconnection interval (ms) | | reconnectBackoffFactor | number | 2 | Exponential backoff factor | | enableHeartbeat | boolean | false | Enable heartbeat monitoring | | heartbeatInterval | number | 30000 | Heartbeat interval (ms) | | heartbeatTimeout | number | 5000 | Heartbeat timeout (ms) | | secure | boolean | false | Use WSS instead of WS | | name | string | undefined | Client identifier |

📚 API Documentation

📖 Full API documentation is available at: ./docs/index.html

Open docs/index.html in your browser for comprehensive API reference with TypeScript types, examples, and detailed descriptions.

Server API

Constructor

new Server(config: ServerConfig)

Methods

listen(callback?: () => void): void Start the WebSocket server and begin listening for connections.

server.listen(() => {
  console.log('Server started on port 8080');
});

broadcast(message: any, sender?: WebSocket): void Broadcast a message to all connected clients except the sender.

server.broadcast('Hello everyone!');
server.broadcast({ type: 'announcement', content: 'Server restart' });

to(roomName: string): RoomManager Get room manager for targeted broadcasting to a specific room.

server.to('general').broadcast('Message for general room only');

close(callback?: () => void): void Gracefully close the server and all connections.

server.close(() => {
  console.log('Server closed');
});

getConnectionCount(): number Get the current number of connected clients.

const count = server.getConnectionCount();
console.log(`Connected clients: ${count}`);

getAllRooms(): string[] Get list of all active room names.

const rooms = server.getAllRooms();
console.log('Active rooms:', rooms);

getRoomClients(roomName: string): Set<WebSocket> | undefined Get all clients in a specific room.

const clients = server.getRoomClients('general');
console.log(`Clients in general room: ${clients?.size}`);

Client API

Constructor

new Client(config: ClientConfig)

Methods

connect(): void Establish connection to the WebSocket server.

send(message: any): void Send a message to the server.

client.send('Hello world!');
client.send({ type: 'chat', content: 'Hi!' });
client.send({ sender: 'user1', data: 'Custom message' });

join(roomName: string): void Join a chat room for targeted messaging.

client.join('general');
client.join('support');

leave(roomName: string): void Leave a chat room.

client.leave('general');

close(): void Close the WebSocket connection gracefully.

isConnected(): boolean Check if the client is currently connected.

getReconnectAttempts(): number Get the current reconnection attempt count.

Events

open Connection established.

message Message received from server.

close Connection closed.

error Error occurred.

reconnecting Attempting to reconnect.

heartbeat Heartbeat received.

💡 Examples

Basic Connection

// server.ts
import { Server } from '@onurege3467/workspaces'

const server = new Server({
  port: 8080,
  token: 'secret'
})

server.listen()

// client.ts
import { Client } from '@onurege3467/workspaces'

const client = new Client({
  address: 'localhost:8080',
  token: 'secret'
})

client.connect()

Encrypted Chat

// server.ts
const server = new Server({
  port: 8080,
  token: 'secret',
  enableEncryption: true
})

// client.ts
const client = new Client({
  address: 'localhost:8080',
  token: 'secret',
  enableEncryption: true
})

client.on('message', (msg) => console.log('Secure:', msg))
client.connect()

Room-Based Messaging

// server.ts
const server = new Server({
  port: 8080,
  token: 'secret',
  enableRooms: true
})

// Broadcast to specific room
server.to('general').broadcast({ type: 'msg', content: 'Hello general!' })
server.to('support').broadcast({ type: 'msg', content: 'Hello support!' })

// client.ts
client.on('open', () => {
  client.join('general')
})

client.send({ type: 'msg', content: 'My message' })

Heartbeat & Reconnection

// client.ts
const client = new Client({
  address: 'localhost:8080',
  token: 'secret',
  enableHeartbeat: true,
  reconnectInterval: 5000,
  reconnectMaxInterval: 60000,
  reconnectBackoffFactor: 2
})

client.on('reconnecting', () => {
  console.log('Attempting to reconnect...');
})

client.on('heartbeat', () => {
  console.log('Connection is alive');
})

Rate Limiting

// server.ts
const server = new Server({
  port: 8080,
  token: 'secret',
  enableRateLimit: true,
  rateLimitMaxRequests: 50,  // 50 requests
  rateLimitWindowMs: 60000   // per minute
})

// Check remaining requests for an IP
const remaining = server.getRateLimitRemaining('192.168.1.1');
console.log(`Remaining requests: ${remaining}`);

🔒 Security Features

End-to-End Encryption

The package uses Diffie-Hellman key exchange for secure key generation and AES-256-GCM for message encryption with PBKDF2 key derivation:

  1. Client generates public/private key pair using Diffie-Hellman
  2. Server generates its own key pair
  3. Both parties exchange public keys
  4. Shared secret is computed using Diffie-Hellman
  5. AES-256-GCM key is securely derived from shared secret using PBKDF2 with 100,000 iterations
  6. All messages are encrypted with this key and include integrity protection

Rate Limiting

Built-in rate limiting protects against abuse:

  • Configurable request limits per IP address
  • Sliding window time periods
  • Automatic cleanup of old requests
  • Returns HTTP 429 when limits exceeded

Authentication & Authorization

  • Token Authentication: Required for all connections
  • IP Whitelisting: Restrict access to specific IP addresses
  • CORS Support: Configurable cross-origin policies

Input Validation

  • All cryptographic operations include comprehensive input validation
  • JSON parsing with proper error handling
  • Buffer length validation for encryption keys

🔧 Development

# Build the project
npm run build

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Generate API documentation
npm run docs

📖 Troubleshooting

Common Issues

Connection Refused

  • Check if server is running on the correct port
  • Verify token matches between client and server
  • Check IP whitelist if enabled

Encryption Errors

  • Ensure both client and server have encryption enabled
  • Check network connectivity for key exchange
  • Verify compatible Node.js version

Rate Limiting

  • Check rate limit configuration
  • Monitor server logs for rate limit violations
  • Adjust limits based on your use case

Room Messages Not Received

  • Ensure rooms are enabled on server
  • Verify client has joined the correct room
  • Check room name spelling

Debug Mode

Enable debug logging:

// Server
const server = new Server({
  // ... config
  enableDebug: true
})

// Client
const client = new Client({
  // ... config
  enableDebug: true
})

Performance Tuning

For high-traffic applications:

const server = new Server({
  port: 8080,
  token: 'secret',
  maxConnections: 10000,
  enableCompression: true,
  compressionThreshold: 512, // Lower threshold
  enableRateLimit: true,
  rateLimitMaxRequests: 1000,
  rateLimitWindowMs: 60000
})

⚠️ DANGER: Remote Code Execution ⚠️

🚨 SECURITY WARNING: Remote code execution is EXTREMELY DANGEROUS and should NEVER be enabled in production environments unless you are in a completely trusted environment with proper security measures in place.

Why It's Dangerous:

  • Arbitrary Code Execution: Attackers can run any code on your server
  • System Compromise: File system access, network access, privilege escalation
  • Data Breach: Sensitive data theft, database manipulation
  • Denial of Service: Infinite loops, memory exhaustion, resource abuse
  • Backdoors: Malicious code can create persistent access

Configuration (Default: DISABLED)

const server = new Server({
  port: 8080,
  token: 'secret',
  enableCodeExecution: false, // ⚠️ KEEP THIS FALSE!
  codeExecutionTimeout: 5000, // 5 second timeout
  codeExecutionMemoryLimit: 128 * 1024 * 1024 // 128MB limit
});

Security Measures (If You Must Use It):

  • Only enable in isolated, air-gapped environments
  • Use VM2 sandboxing with strict timeouts
  • Implement comprehensive input validation
  • Block dangerous functions (require, fs, process, etc.)
  • Use rate limiting and IP whitelisting
  • Monitor execution logs continuously
  • Regular security audits

Example Usage (FOR EDUCATIONAL PURPOSES ONLY)

import { VM } from 'vm2';

// ⚠️ DANGER: Only for trusted environments!
const server = new Server({
  port: 8080,
  token: 'secret',
  enableCodeExecution: true, // ⚠️ NEVER DO THIS IN PRODUCTION!
  enableEncryption: true,
  enableRateLimit: true
});

// Handle code execution (with security checks)
server.on('connection', (client) => {
  client.on('message', async (message) => {
    if (message.type === 'execute_code') {
      try {
        // Security validation
        if (message.code.length > 10000) {
          throw new Error('Code too large');
        }

        // Dangerous patterns check
        const dangerous = /require|fs\.|process\.|eval\(/;
        if (dangerous.test(message.code)) {
          throw new Error('Dangerous code pattern detected');
        }

        // Execute in sandbox
        const vm = new VM({
          timeout: 5000,
          sandbox: {
            console: { log: (...args) => console.log('[VM]', ...args) },
            Math, Date, JSON, Array, Object
          }
        });

        const result = vm.run(message.code);

        client.send({
          type: 'execution_result',
          success: true,
          result: result
        });

      } catch (error: any) {
        client.send({
          type: 'execution_error',
          success: false,
          error: error.message
        });
      }
    }
  });
});

// Client (also dangerous if not trusted)
const client = new Client({
  address: 'localhost:8080',
  token: 'secret',
  enableEncryption: true
});

client.send({
  type: 'execute_code',
  code: `
    // Safe example: mathematical computation
    const fibonacci = (n) => n <= 1 ? n : fibonacci(n-1) + fibonacci(n-2);
    const result = {
      fibonacci_10: fibonacci(10),
      timestamp: Date.now(),
      calculation: Math.pow(2, 8) + Math.PI
    };
    result;
  `
});

🚫 NEVER Use This In Production

  • Web applications open to internet
  • Multi-user systems
  • Financial applications
  • Healthcare systems
  • Government systems
  • Any system handling sensitive data

Use only in: Isolated development environments, educational demos, trusted internal networks with proper security controls.

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

ISC


Made with ❤️ by @onurege3467