
Company News
Socket Named Top Sales Organization by RepVue
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.
playsocketjs
Advanced tools
A reactive, optimistic WebSocket library that simplifies game & app development by abstracting away complex sync logic.
PlaySocket eliminates the traditional complexity of collaborative experiences:
npm install playsocketjs
Note that in production, you should always try...catch promises, such as socket.init() – they can reject!
Initializing the client:
import PlaySocket from 'playsocketjs';
// Create a new instance
const socket = new PlaySocket('unique-client-id', { // You can pass no ID to let the server pick one
endpoint: 'wss://example.com/socket'
});
// Set up event handlers (optional)
socket.onEvent('status', status => console.log('Status:', status));
socket.onEvent('error', status => console.log('Error:', status));
const clientId = await socket.init(); // Initialize the socket
Creating a room:
// Create a new room
const roomId = await socket.createRoom();
// Optionally, with initial storage
const roomId = await socket.createRoom({
players: ["this-player"],
latestPlayer: null,
});
Joining a room:
await socket.joinRoom('room-id'); // Join an existing room
Leaving a room:
socket.destroy(); // To leave the room, destroy the instance
Using the storage update event for reactivity:
const reactiveVariable = useState(); // Or $state(), reactive(), depending on your framework
socket.onEvent('storageUpdated', storage => (reactiveVariable = storage)); // Assign on update
Interfacing with the synchronized storage (examples):
const currentState = socket.storage; // Synchronous, local access
socket.updateStorage('players', 'array-add-unique', { username: 'Player4', level: 2 }); // Special method to enable conflict-free additions for arrays
socket.updateStorage('latestPlayer', 'set', 'Player4'); // Regular synced storage update
Sending traditional requests to the server:
socket.sendRequest('chosen-request-name', { fact: "You can build server-authoritative logic using this!" })
Creates a new PlaySocket instance with a specified ID and configuration options.
The ID can be set to null to let the server pick a unique one.
new PlaySocket(id?: string, options: PlaySocketOptions)
| Option | Type | Default | Description |
|---|---|---|---|
endpoint | string | undefined | WebSocket server endpoint (e.g., 'wss://example.com/socket') (required) |
customData | object | {} | Arbitrary data to pass to the "clientRegistered" server event |
debug | boolean | false | Set to true to enable extra logging |
| Method | Parameters | Return type | Description |
|---|---|---|---|
init() | - | Promise<string> | Initialize the WebSocket connection – Returns a promise which resolves with the client's ID |
createRoom() | initialStorage?: object, size?: number | Promise<string> | Create a new room and become host – Returns a promise which resolves with the room ID. The room participant maximum is 100 |
joinRoom() | roomId: string | Promise<void> | Join an existing room |
destroy() | - | void | Use this to leave a room and close the connection |
updateStorage() | key: string, type: 'set' | 'array-add' | 'array-add-unique' | 'array-remove-matching' | 'array-update-matching', value: any, updateValue?: any | void | Update a key in the shared storage (max. 100 keys). Array operation types allow for conflict-free simultaneous array updates. For '-matching' operations, value becomes the value to match, and updateValue the replacement |
sendRequest() | name: string, data?: any | void | Send requests to the server with optional custom data (handle them in the requestReceived server event) |
onEvent() | event: string, callback: Function | void | Register an event callback |
| Event | Callback parameter | Description |
|---|---|---|
status | status: string | Connection status updates |
error | error: string | Error events |
moved | roomId: string | Moved to different room |
instanceDestroyed | - | Destruction event - triggered by manual .destroy() method invocation or by fatal errors and disconnects |
storageUpdated | storage: object | Storage state changes |
hostMigrated | roomId: string | Host changes |
clientJoined | clientId: string | New client joined the room |
clientLeft | clientId: string, roomId?: string | Client left the room |
| Property | Type | Description |
|---|---|---|
id | string | Client's unique identifier on the WebSocket server |
isHost | boolean | If this user is currently assigned the host role |
participantCount | number | Number of active client connections in room (with yourself) |
storage | object | Retrieve storage object |
PlaySocket includes a server implementation that can be set up in seconds.
To use the server component, you'll need to install playsocketjs and the ws package:
npm install playsocketjs ws
Here are usage examples for a standalone server and an Express.js application.
import PlaySocketServer from 'playsocketjs/server'; // Both ES Module & CommonJS Module syntax is supported
const server = new PlaySocketServer(); // Create and start the server (default path is /)
// Gracefully disconnect all clients and close the server (optional)
function shutdown() {
server.stop();
process.exit(0);
}
// Handle both SIGINT and SIGTERM
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
const express = require('express');
const http = require('http');
const PlaySocketServer = require('playsocketjs/server');
const app = express();
const httpServer = http.createServer(app);
// Create PlaySocket server with your HTTP server
const playSocketServer = new PlaySocketServer({
server: httpServer,
path: '/socket'
});
// Start the server
httpServer.listen(3000, () => {
console.log('Server running on port 3000');
});
// Gracefully disconnect all clients and close the server (recommended)
function shutdown() {
server.stop();
process.exit(0);
}
// Handle both SIGINT and SIGTERM
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
Creates a new PlaySocket Server instance with configuration options.
new PlaySocket(options: PlaySocketServerOptions)
| Option | Type | Default | Description |
|---|---|---|---|
port | number | 3000 | Port to listen on (used only if no server provided) |
path | string | '/' | WebSocket endpoint path |
server | http.Server | - | Existing http server (optional) |
rateLimit | number | 20 | Adjust the messages/second rate limit |
debug | boolean | false | Set to true to enable extra logging |
verifyClient | function | - | Optional callback to verify connections before WebSocket upgrade |
The verifyClient option allows you to implement custom connection verification logic, such as rate limiting, before the WebSocket handshake completes.
const server = new PlaySocketServer({
server: httpServer,
path: '/socket',
verifyClient: (info, callback) => {
// info.req - the HTTP request object, info.origin - the Origin header value
const ip = info.req.headers['x-forwarded-for'] || info.req.socket.remoteAddress;
if (isRateLimited(ip)) return callback(false, 429, 'Too Many Requests');
callback(true);
}
});
The callback signature is callback(verified, code?, message?) where code and message are the optional HTTP response status for rejected connections.
| Method | Parameters | Return type | Description |
|---|---|---|---|
stop() | - | void | Closes all active client connections, the websocket server and the underlying http server if it's standalone |
kick() | clientId: string, reason?: string | void | Kick a client by their clientID – this will close their connection and set an error message |
move() | clientId: string, roomId: string | void | Move a client, that is already in a room, to a different room |
onEvent() | event: string, callback: Function | void | Register a server-side event callback |
getRoomStorage() | roomId: string | object | Get a snapshot of the current room storage |
updateRoomStorage() | roomId: string, key: string, type: 'set' | 'array-add' | 'array-add-unique' | 'array-remove-matching' | 'array-update-matching', value: any, updateValue?: any | void | Update a key in the shared room storage from the server |
createRoom() | initialStorage?: object, size?: number, host?: string | object | Create a room (returns object containing room ID and state) |
destroyRoom() | roomId: string | void | Destroy a room & kick all participants |
| Event | Callback parameters | Description | Return for action |
|---|---|---|---|
clientRegistered | clientId: string, customData: object | Client registered with the server | - |
clientRegistrationRequested | clientId: string, customData: object | Client requests to register | Return false or rejection reason string to block |
clientDisconnected | clientId: string | Client disconnected from the server | - |
clientJoinedRoom | clientId: string, roomId: string | Client joined a room | - |
clientJoinRequested | clientId: string, roomId: string | Client requests to join a room | Return false or rejection reason string to block |
clientLeftRoom | clientId: string, roomId: string | Client left a room | - |
roomCreated | roomId: string | Client created a room | - |
roomDestroyed | roomId: string | Room was destroyed (happens when all participants leave, unless room host is "server") | - |
roomCreationRequested | {clientId: string, initialStorage: object} | Room creation requested by client | Return object to override initial storage, false to deny |
storageUpdated | {clientId: string, roomId: string, update: object, storage: object} | Room storage property updated | - |
storageUpdateRequested | {clientId: string, roomId: string, update: object, storage: object} | Room storage property update requested by client | Return false to block the update |
requestReceived | {clientId: string, roomId?: string, requestName: string, data?: any} | Request from client was received by the server | - |
| Property | Type | Description |
|---|---|---|
rooms | object | Retrieve the rooms object |
MIT
FAQs
WebSocket wrapper for creating simple multiplayer systems with ease.
We found that playsocketjs demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.

Company News
/Security News
Socket is an initial recipient of OpenAI's Cybersecurity Grant Program, which commits $10M in API credits to defenders securing open source software.