OverviewHistoryStatsSecurity
npx skills add ...
Documentation
SKILL.md
npx skills add claude-dev-suite/claude-dev-suite --skill socket-io
Socket.IO real-time bidirectional communication. Rooms, namespaces, acknowledgments, middleware, scaling with Redis adapter, and TypeScript types.
npx skills add claude-dev-suite/claude-dev-suite --skill socket-io
| Anti-Pattern | Fix |
|---|---|
| No authentication | Use io.use() middleware with JWT |
| Broadcasting to all instead of rooms | Use socket.to(room).emit() |
| No reconnection handling | Enable reconnection, show UI indicator |
| Single server without adapter | Use Redis adapter for horizontal scaling |
| No acknowledgments for critical events | Use callback parameter for delivery confirmation |
import { io, Socket } from 'socket.io-client';
const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io(API_URL, {
auth: { token: getAuthToken() },
reconnection: true,
reconnectionDelay: 1000,
});
socket.on('connect', () => console.log('Connected'));
socket.on('message', (data) => addMessage(data));
socket.on('connect_error', (err) => console.error(err.message));
// With acknowledgment
socket.emit('sendMessage', 'Hello!', (status) => {
if (status === 'error') showError('Failed to send');
});import { createAdapter } from '@socket.io/redis-adapter';
import { createClient } from 'redis';
const pubClient = createClient({ url: process.env.REDIS_URL });
const subClient = pubClient.duplicate();
await Promise.all([pubClient.connect(), subClient.connect()]);
io.adapter(createAdapter(pubClient, subClient));function useSocket(room: string) {
const [messages, setMessages] = useState<Message[]>([]);
useEffect(() => {
socket.emit('joinRoom', room);
socket.on('message', (msg) => setMessages((prev) => [...prev, msg]));
return () => { socket.off('message'); };
}, [room]);
const send = (text: string) => socket.emit('sendMessage', text, () => {});
return { messages, send };
}