
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
Build realtime apps on Cloudflare with Socket.io-like simplicity
Verani brings the familiar developer experience of Socket.io to Cloudflare's Durable Objects (Actors), with proper hibernation support and minimal overhead. Build realtime chat, presence systems, notifications, and more—all running on Cloudflare's edge.
Get a realtime chat app running in 5 minutes.
npm install verani @cloudflare/actors
Don't have a Cloudflare Worker project? Create one:
npm create cloudflare@latest my-verani-app
cd my-verani-app
npm install verani @cloudflare/actors
Create src/actors/connection.ts:
import { defineConnection, createConnectionHandler, createRoomHandler } from "verani";
// Define connection handler (one WebSocket per user)
const userConnection = defineConnection({
name: "UserConnection",
extractMeta(req) {
const url = new URL(req.url);
const userId = url.searchParams.get("userId") || crypto.randomUUID();
return {
userId,
clientId: crypto.randomUUID(),
channels: ["default"]
};
},
async onConnect(ctx) {
console.log(`User ${ctx.meta.userId} connected`);
// Join chat room (persisted across hibernation)
await ctx.actor.joinRoom("chat");
},
async onDisconnect(ctx) {
console.log(`User ${ctx.meta.userId} disconnected`);
// Room leave is handled automatically
}
});
// Handle messages (socket.io-like API)
userConnection.on("chat.message", async (ctx, data) => {
// Broadcast to everyone in the chat room
await ctx.emit.toRoom("chat").emit("chat.message", {
from: ctx.meta.userId,
text: data.text,
timestamp: Date.now()
});
});
// Export the connection handler
export const UserConnection = createConnectionHandler(userConnection);
// Export the room coordinator
export const ChatRoom = createRoomHandler({ name: "ChatRoom" });
Update src/index.ts:
import { UserConnection, ChatRoom } from "./actors/connection";
// Export Durable Object classes
export { UserConnection, ChatRoom };
// Route WebSocket connections
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext) {
const url = new URL(request.url);
if (url.pathname.startsWith("/ws")) {
// Extract userId and route to user-specific DO
const userId = url.searchParams.get("userId") || crypto.randomUUID();
const stub = UserConnection.get(userId);
return stub.fetch(request);
}
return new Response("Not Found", { status: 404 });
}
};
Update wrangler.jsonc:
{
"name": "my-verani-app",
"main": "src/index.ts",
"compatibility_date": "2025-11-26",
"durable_objects": {
"bindings": [
{
"class_name": "UserConnection",
"name": "CONNECTION_DO"
},
{
"class_name": "ChatRoom",
"name": "ROOM_DO"
}
]
},
"migrations": [
{
"new_sqlite_classes": ["UserConnection", "ChatRoom"],
"tag": "v1"
}
]
}
Important: Export names must match class_name in wrangler.jsonc.
import { VeraniClient } from "verani/client";
const client = new VeraniClient("ws://localhost:8787/ws?userId=alice");
// Listen for messages
client.on("chat.message", (data) => {
console.log(`${data.from}: ${data.text}`);
});
client.on("user.joined", (data) => {
console.log(`User ${data.userId} joined!`);
});
// Send messages
client.emit("chat.message", { text: "Hello, world!" });
// Wait for connection (optional)
await client.waitForConnection();
# Start the server
npm run dev
# or
wrangler dev
# In another terminal, run your client
# (or open multiple browser tabs with your client code)
That's it! You now have a working realtime chat app.
Need more help? Check out the Quick Start Guide for detailed examples.
ctx.emit.toRoom("chat").emit("event", data))connection.on(), ctx.emit.toRoom(), familiar patternsonConnect, onDisconnect, onMessage for full controlon(), emit(), once(), off() methodsconnecting, connected, disconnected)See Verani in action with working examples:
git clone https://github.com/v0id-user/verani
cd verani
bun install && bun run dev
Then in another terminal, try:
# Chat room example
bun run examples/clients/chat-client.ts
# Presence tracking
bun run examples/clients/presence-client.ts
# Notifications feed
bun run examples/clients/notifications-client.ts
See the Examples README for more details.
Vchats - A complete chat application built with Verani
ISC
Contributions welcome! Please read our Contributing Guidelines first.
FAQs
A simple, focused realtime SDK for Cloudflare Actors with Socket.io-like semantics
We found that verani 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.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.