Coming from Socket.io
Concept mapping
| Socket.io | svelte-realtime |
|---|---|
io.emit('event', data) | ctx.publish(topic, event, data) |
socket.on('event', cb) | $live/module store subscription |
io.to(room).emit(...) | Topic-scoped publishing |
| Rooms | Topics (first arg to live.stream()) |
socket.join(room) | Automatic on stream subscription |
Middleware (io.use()) | upgrade() + guard() |
| Acknowledgements | RPC return values |
socket.broadcast.emit(...) | ctx.publish() (always broadcasts) |
| Namespaces | Separate files in src/live/ |
socket.id | ctx.user.id (from upgrade()) |
Side-by-side: Chat app
Socket.io
// Server
const io = require('socket.io')(server);
io.use((socket, next) => {
const token = socket.handshake.auth.token;
const user = verifyToken(token);
if (!user) return next(new Error('unauthorized'));
socket.user = user;
next();
});
io.on('connection', (socket) => {
socket.join('chat');
socket.on('sendMessage', (text, callback) => {
const msg = { id: Date.now(), text, userId: socket.user.id };
io.to('chat').emit('newMessage', msg);
callback(msg);
});
}); // Client
const socket = io({ auth: { token } });
socket.on('newMessage', (msg) => {
messages = [...messages, msg];
});
socket.emit('sendMessage', text, (response) => {
console.log('sent:', response);
}); 34 lines. Manual event wiring, callback-based acknowledgements, manual room management.
svelte-realtime
// src/live/chat.js
import { live } from 'svelte-realtime/server';
export const sendMessage = live(async (ctx, text) => {
const msg = { id: crypto.randomUUID(), text, userId: ctx.user.id };
ctx.publish('messages', 'created', msg);
return msg;
});
export const messages = live.stream('messages', () => [], {
merge: 'crud', key: 'id'
}); <script>
import { sendMessage, messages } from '$live/chat';
</script>
{#each $messages as msg (msg.id)}
<p>{msg.text}</p>
{/each} 17 lines. No event listeners, no callbacks, no room management. The stream is a Svelte store.
Key differences
- No event names. Socket.io requires matching string event names between emit and on. svelte-realtime uses typed imports - typos are caught by the bundler.
- No manual rooms. Topics are automatic. Subscribe to a stream and you’re in the room.
- RPC, not callbacks.
sendMessage(text)returns a promise. No callback argument, no acknowledgement protocol. - Merge strategies. Socket.io gives you raw events - you manage state yourself. svelte-realtime merges events into stores automatically.
Migration steps
- Replace
io.use()middleware withupgrade()inhooks.ws.js - Replace
socket.on('event', cb)listeners withlive.stream()subscriptions - Replace
socket.emit('event', data, cb)withlive()RPC calls - Replace
io.to(room).emit()withctx.publish(topic, event, data) - Remove all client-side event listener boilerplate -
$live/*stores handle it
Was this page helpful?