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

hermes-ws

v0.2.0

Published

A minimal RFC 6455 WebSocket server and Vite plugin for Node.js.

Readme

hermes-ws

一个基于 Node.js、面向 Vite 开发环境的最小 WebSocket Server 实现。

项目直接实现 RFC 6455 的基础帧、握手和连接生命周期,不依赖 ws 或 socket.io。

它的目标不是提供完整的 WebSocket 生态,而是提供一个体积小、依赖少、职责明确的基础 WebSocket Server。

特性

  • HTTP Upgrade / 101 握手
  • Sec-WebSocket-Key
  • WebSocket Version 13
  • Upgrade / Connection 校验
  • Text / Binary 消息
  • Ping / Pong
  • Close
  • UTF-8 校验
  • MASK 校验
  • RSV 校验
  • Control Frame 限制
  • maxPayload 限制
  • TCP 粘包 / 拆包
  • initialData(握手 head 中携带的首帧)
  • 客户端集合
  • Broadcast
  • Server 生命周期
  • Vite Plugin

明确不做

  • 不支持消息分片
  • 不支持 WebSocket Extensions
  • 不支持 permessage-deflate
  • 不负责认证
  • 不负责重连
  • 不负责心跳框架
  • 不负责 RPC / room / subscription
  • 不负责业务协议

业务协议应当建立在 hermes-ws 之上,而不是进入核心。

安装

Monorepo 内使用

import { hermesWs } from "#/hermes-ws";

作为 npm 包使用

npm install hermes-ws
import { hermesWs } from "hermes-ws";

Server 用法

import { createServer } from "node:http";
import { MinimalWebSocketServer } from "hermes-ws";

const wss = new MinimalWebSocketServer({
  maxPayload: 16 * 1024 * 1024,
});

wss.on("connection", (ws) => {
  console.log("client connected");

  ws.on("message", (message, isBinary) => {
    if (isBinary) {
      ws.send(message);
    } else {
      ws.send(`echo: ${message}`);
    }
  });

  ws.on("close", (code, reason) => {
    console.log("client closed", code, reason.toString());
  });

  ws.on("error", (error) => {
    console.error(error);
  });
});

const server = createServer();

server.on("upgrade", (req, socket, head) => {
  const { pathname } = new URL(req.url, "http://localhost");

  if (pathname !== "/ws") return;

  wss.handleUpgrade(req, socket, head, (ws) => {
    wss.emit("connection", ws, req);
  });
});

server.listen(3000);

Vite Plugin 用法

import { defineConfig } from "vite";
import { hermesWs } from "hermes-ws";

export default defineConfig({
  plugins: [
    hermesWs({
      path: "/ws",
      maxPayload: 16 * 1024 * 1024,

      onConnection(ws, wss) {
        ws.on("message", (message) => {
          wss.broadcast(message);
        });
      },
    }),
  ],
});

hermesWs 只负责:

  • Vite upgrade
  • 路径匹配
  • WebSocket Server 生命周期

业务逻辑全部通过 onConnection 注入。

客户端用法

客户端不需要引入 hermes-ws,直接使用浏览器原生 WebSocket:

const ws = new WebSocket("ws://localhost:3000/ws");

ws.onopen = () => {
  ws.send("hello");
};

ws.onmessage = (event) => {
  console.log(event.data);
};

ws.onclose = (event) => {
  console.log(event.code, event.reason);
};

Connection API

ws.send("hello");
ws.send(Buffer.from([1, 2, 3]));

ws.ping();
ws.pong();

ws.close(1000, "bye");
ws.destroy();

ws.readyState;

事件:

ws.on("message", (message, isBinary) => {});
ws.on("close", (code, reason) => {});
ws.on("error", (error) => {});
ws.on("pong", (data) => {});

使用 MinimalWebSocket 时建议始终监听 error 事件;Node.js 的 EventEmitter 对未处理的 error 事件会抛出异常。

Server API

const wss = new MinimalWebSocketServer({
  maxPayload: 16 * 1024 * 1024,
});

wss.on("connection", (ws) => {});

wss.broadcast("hello everyone");
wss.broadcast("hello others", ws);

wss.close(callback);

架构

Vite
  │
  ▼
hermesWs() / MinimalWebSocketServer
  │
  ├── handshake
  ├── connection
  ├── clients
  └── broadcast
          │
          ▼
      MinimalWebSocket
          │
          ├── send / ping / pong / close / destroy
          └── message / close / error / pong
                  │
                  ▼
              Frame Codec
                  │
                  ▼
              TCP Socket

测试

bun test
bunx tsc --noEmit

当前测试覆盖:

  • Frame 编解码
  • 7 / 16 / 64 位长度
  • Text / Binary
  • Ping / Pong
  • Close
  • 粘包 / 拆包
  • initialData
  • MASK / RSV / FIN
  • UTF-8
  • maxPayload
  • Broadcast
  • Server 生命周期
  • Vite Plugin
  • 真实 TCP Integration Test

协议边界

支持:

TEXT + FIN
BINARY + FIN
PING + FIN
PONG + FIN
CLOSE + FIN

拒绝:

TEXT + !FIN
BINARY + !FIN
CONTINUATION

版本

当前版本:0.1.0