sveltekit-websockets
    Preparing search index...

    sveltekit-websockets

    @sourceregistry/sveltekit-websockets

    npm version License CI

    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.


    • 🔌 Per-request WebSockets tied to SvelteKit form actions
    • 🔁 Persistent WebSocket routes via controller-based routing
    • 🧠 Lifecycle hooks: connect, disconnect, error, destroy
    • 🧩 Reactive Svelte component with auto-connect and snippets for streamed messages
    • ⚙️ Vite plugin that wires up .upgrade() handling in dev and preview
    • 🔐 Ephemeral, single-use connection keys with TTL and automatic cleanup

    npm 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.port to 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 dedicated ws.port it gets killed too — the browser loses its HMR connection, keeps retrying, and the page reloads in a loop.

    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);
    });
    }),
    }),
    };

    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