Typed WebSocket infrastructure for SvelteKit — per-request or continuous connections, full back-end lifecycle, and a reactive Svelte component for the client.
⚠️ Node-only. This package requires
@sveltejs/adapter-node. WebSockets are not supported on serverless or edge adapters.
connect, disconnect, error, destroy.upgrade() handling in dev and previewnpm install @sourceregistry/sveltekit-websockets
WebSocket upgrades need a hook into the dev/preview HTTP server. Add the plugin in vite.config.ts:
import {defineConfig} from 'vite';
import {sveltekit} from '@sveltejs/kit/vite';
import {websockets} from '@sourceregistry/sveltekit-websockets/vite';
export default defineConfig({
plugins: [
sveltekit(),
websockets(), // ADD THIS — after sveltekit()
],
server: {
ws: {
port: 5174, // REQUIRED — see note below
},
},
});
Without the plugin, .upgrade() requests fail in dev and preview (production builds on adapter-node are
patched automatically at build time; SvelteKit 2 and 3, adapter-node 5 and 6). Keep websockets() after
sveltekit(): on SvelteKit 3 the build entry is written after the adapter has run, in plugin order.
⚠️ Also set
server.ws.portto a different port, as shown above. The plugin intercepts every'upgrade'request on the dev server's HTTP port and closes any that don't match a registered route. Vite's own HMR client connects over a WebSocket on that same port by default, so without a dedicatedws.portit gets killed too — the browser loses its HMR connection, keeps retrying, and the page reloads in a loop.
use())Bind a single-use WebSocket to a SvelteKit form action. The client gets back a one-time URL that expires automatically.
// src/routes/chat/+page.server.ts
import {websockets} from '@sourceregistry/sveltekit-websockets/server';
export const actions = {
ws: (event) => ({
url: websockets.use(event, (socket) => {
socket.send('Connected!');
socket.addEventListener('message', (msg) => {
console.log('Client says:', msg.data);
});
}),
}),
};
continuous())Register a long-lived endpoint independent of any single request, typically from src/hooks.server.ts:
import {websockets} from '@sourceregistry/sveltekit-websockets/server';
const chat = websockets.continuous('/chat', {useConnectionKeys: false});
chat.on('connect', (socket) => {
socket.send('Welcome to /chat');
socket.addEventListener('message', (msg) => socket.send(`Echo: ${msg.data}`));
});
Now reachable at ws://localhost:5173/chat.
{#snippet message(data)}
{new Date().toLocaleTimeString()}: {data}
{/snippet}
| Prop | Type | Description |
|---|---|---|
action |
string |
Form action that returns { url } |
url |
string |
Direct WebSocket URL, as an alternative to action |
data |
T[] |
Bindable, reactive array of received messages |
auto_open |
boolean |
Auto-connect on mount (default: true) |
controller |
snippet | Render callback for manual open() / close() |
message |
snippet | Render callback per received message |
For every configuration option, server event, low-level socket API (broadcast, send, raw(),
graceful shutdown, rate limiting, timeouts, etc.), and the client-side Action/ActionSocket helpers, see
API.md.
See CONTRIBUTING.md.
Apache-2.0