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

@ghuts/disocket

v1.0.1

Published

Zero-dependency native C++ realtime chat engine for Node.js

Readme

@ghuts/disocket

Native C++ realtime chat engine for Node.js with zero runtime dependencies.

@ghuts/disocket is a Socket.io-like chat/live-data package bundled as one npm package. The core engine is a native C++ N-API addon. The JavaScript layer is a thin ergonomic wrapper and the browser client uses the built-in WebSocket API.

Features v1.0.0

  • Native C++ core via direct C N-API, no node-addon-api wrapper.
  • zero runtime dependencies in package.json.
  • Rooms: join, leave, history, visible/hidden presence.
  • Messaging: canonical IDs, room sequence, tempId dedupe, threadId, edit, soft delete/tombstone.
  • Ack-ready packet model through canonical message return values.
  • Moderation: mute, ban enforcement, kick helper, moderator-role checks, audit log, shadow-mute action contract.
  • Reliability primitives: idempotency through tempId, append-only file log, delivery policy option surface.
  • Security: signed HMAC auth tokens via Node built-in crypto, room/user validation, membership enforcement option, role-protected moderation, path-safe file storage names.
  • Abuse controls: max message size, per-socket token bucket rate limit, slow-mode enforcement, max sockets, max rooms per socket.
  • Memory/resource controls: resource stats, max history limit, max messages per room, prune, compact, wipeRoom, close/clear.
  • Room controls: read-only, locked, slow-mode/retention config surface.
  • Reactions and presence.
  • Metrics, health snapshots, and resource snapshots.
  • Bundled browser client under @ghuts/disocket/client with strict packet validation.
  • Manual TypeScript types.
  • Makefile, tests, review script, and npm pack validation.

Install

npm install @ghuts/disocket

From source:

npm install
npm run build
npm test

Quickstart

const { NativeChatServer } = require('@ghuts/disocket');

const secret = process.env.DISOCKET_SECRET || 'dev-secret';
const token = NativeChatServer.issueAuthToken(
  { id: 'u1', name: 'Alice', roles: ['member'] },
  secret,
  { expiresInMs: 60_000 }
);

const chat = new NativeChatServer({
  auth: { mode: 'signed', secret },
  validation: {
    roomPattern: '^[A-Za-z0-9._:-]{1,64}$',
    allowControlChars: false
  },
  permissions: {
    requireJoinBeforeSend: true,
    moderatorRoles: ['mod', 'admin']
  },
  resourceLimits: {
    maxSockets: 10_000,
    maxRoomsPerSocket: 32,
    maxMessagesPerRoom: 10_000,
    maxHistoryLimit: 500,
    messageOverflow: 'prune-oldest'
  },
  storage: { type: 'file', dir: './chat-data' },
  rateLimit: { messagesPerMinute: 120 }
});

const alice = chat.connect({ token });
chat.join(alice.socketId, 'general');

const msg = chat.sendMessage(alice.socketId, 'general', 'halo dunia', {
  tempId: 'tmp-1',
  delivery: 'effectively-once'
});

console.log(msg.id, msg.seq);
console.log(chat.history('general', { limit: 20 }));
console.log(chat.resourceStats({ rooms: true }));

Memory and security operations

// enforce slow mode and lock/read-only controls at runtime
chat.setRoomConfig('general', { slowModeMs: 3000, readOnly: false });

// moderator-only if bySocketId is supplied
chat.moderate({
  action: 'ban',
  userId: 'spammer',
  room: 'general',
  durationMs: 60_000,
  bySocketId: 'sock_mod'
});

// remove tombstones from memory, then rewrite append-only log
chat.prune({ room: 'general', tombstonesOnly: true, compact: true });
chat.compact({ room: 'general', storage: true });

// wipe sensitive room data and remove its log
chat.wipeRoom('secure-room', { removeLog: true, bestEffortSecure: true });

Browser client

const { DisocketClient } = require('@ghuts/disocket/client');
const client = new DisocketClient('ws://localhost:3000/chat').connect();
client.on('message:new', console.log);
client.sendMessage('general', 'halo');

The v1 package ships the protocol/client shape in the bundle. A full native WebSocket listener can be layered on this core without changing the public event contract.

Event contract

Core event names supported by the public API:

  • connection, disconnect
  • room:joined, room:left, room:config:update
  • message:new, message:update, message:delete
  • reaction:add, reaction:remove
  • moderation:mute, moderation:ban, moderation:shadow_mute
  • server:announce

Recommended wire packet:

{
  "v": 1,
  "id": "pkt_1",
  "type": "event",
  "event": "message:create",
  "room": "general",
  "data": { "text": "halo", "tempId": "tmp_1" },
  "ts": 1781090000000
}

Storage

Default storage is memory. File storage writes an append-only NDJSON log per room. Room names are encoded into path-safe filenames to block path traversal:

const chat = new NativeChatServer({ storage: { type: 'file', dir: './data' } });
console.log(chat.roomLogName('general')); // hex_67656e6572616c.log

Logs are stored at:

data/rooms/<encoded-room>.log

Metrics

console.log(chat.metrics());
console.log(chat.health());

Metric fields include active sockets/rooms, total connections/disconnections, received/sent/failed messages.

Development

make all      # install, build, test, review
make test
make pack

Design notes

This package intentionally bundles the native core, JS wrapper, client SDK, types, tests, and docs into a single package instead of splitting Redis/Postgres/client packages. External adapters can be added later behind optional configuration, but v1 keeps the install small and dependency-free.