sveltekit-ws
v1.0.1
Published
WebSocket integration for SvelteKit without external server
Maintainers
Readme
SvelteKit WebSocket
WebSocket integration for SvelteKit without external server - seamlessly works in both development and production.
Features
- 🚀 Zero Configuration - Works out of the box with SvelteKit
- 🔄 Auto Reconnection - Built-in reconnection logic with configurable attempts
- 💪 Type Safe - Full TypeScript support with proper types
- 🔌 No External Server - Integrated directly into Vite dev server and production
- 🎯 Connection Management - Easy broadcast, send to specific clients
- 💗 Heartbeat Support - Automatic ping/pong to keep connections alive
- 🛡️ Client Verification - Custom authentication/authorization hooks
- 📦 Small Bundle - Minimal dependencies
Installation
npm install sveltekit-ws ws
# or
pnpm add sveltekit-ws ws
# or
yarn add sveltekit-ws wsUsage
1. Development Setup (vite.config.ts)
import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";
import { webSocketServer } from "sveltekit-ws/vite";
import { getWebSocketManager } from "sveltekit-ws";
export default defineConfig({
plugins: [
// ⚠️ WebSocket plugin MUST be before sveltekit()
webSocketServer({
path: "/ws", // WebSocket endpoint
handlers: {
onConnect: (connection) => {
console.log("Client connected:", connection.id);
const manager = getWebSocketManager();
manager.send(connection.id, {
type: "welcome",
data: { message: "Hello!" },
});
},
onMessage: (connection, message) => {
console.log("Message:", message);
const manager = getWebSocketManager();
// Echo back
manager.send(connection.id, {
type: "echo",
data: message.data,
});
// Broadcast to all except sender
manager.broadcast({ type: "broadcast", data: message.data }, [
connection.id,
]);
},
onDisconnect: (connection) => {
console.log("Client left:", connection.id);
},
},
}),
sveltekit(),
],
});2. Production Setup (server.js)
For production with @sveltejs/adapter-node:
import { handler } from "./build/handler.js";
import express from "express";
import { createServer } from "http";
import { createWebSocketHandler } from "sveltekit-ws/server";
import { getWebSocketManager } from "sveltekit-ws";
const app = express();
const server = createServer(app);
// Setup WebSocket
createWebSocketHandler(server, {
path: "/ws",
handlers: {
onConnect: (connection) => {
const manager = getWebSocketManager();
manager.send(connection.id, {
type: "welcome",
data: { message: "Connected!" },
});
},
onMessage: (connection, message) => {
const manager = getWebSocketManager();
manager.broadcast({ type: "chat", data: message.data });
},
},
});
// SvelteKit handler
app.use(handler);
const PORT = process.env.PORT || 3000;
server.listen(PORT);3. Client Side (Svelte Component)
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { browser } from '$app/environment';
let ws: WebSocket | null = null;
let messages: any[] = [];
let connected = false;
onMount(() => {
if (!browser) return;
ws = new WebSocket(`ws://${window.location.host}/ws`);
ws.onopen = () => {
connected = true;
console.log('Connected!');
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
messages = [...messages, message];
};
ws.onclose = () => {
connected = false;
console.log('Disconnected');
};
});
onDestroy(() => {
ws?.close();
});
function sendMessage(text: string) {
if (ws && connected) {
ws.send(JSON.stringify({
type: 'chat',
data: { text }
}));
}
}
</script>
<div>
<p>Status: {connected ? '🟢 Connected' : '🔴 Disconnected'}</p>
{#each messages as msg}
<div>{msg.type}: {JSON.stringify(msg.data)}</div>
{/each}
<button on:click={() => sendMessage('Hello!')}>
Send
</button>
</div>Advanced Usage
Using the WebSocket Store
import { createWebSocketStore } from "./websocket-store";
// Create store with auto-reconnection
const ws = createWebSocketStore({
url: "ws://localhost:3000/ws",
reconnect: true,
reconnectAttempts: 5,
reconnectDelay: 3000,
onMessage: (message) => {
console.log("Received:", message);
},
});
// Connect
ws.connect();
// Send message
ws.send({ type: "chat", data: { text: "Hello!" } });
// Type-safe send
ws.sendTyped("chat", { text: "Hello!" });
// Disconnect
ws.disconnect();Connection Management
import { getWebSocketManager } from "sveltekit-ws";
const manager = getWebSocketManager();
// Get all connections
const connections = manager.getConnections();
// Get specific connection
const conn = manager.getConnection("connection-id");
// Send to specific client
manager.send("connection-id", {
type: "private",
data: { message: "Only for you" },
});
// Broadcast to all
manager.broadcast({
type: "announcement",
data: { message: "Hello everyone!" },
});
// Broadcast to all except some
manager.broadcast(
{ type: "message", data: "Hello!" },
["id-1", "id-2"] // exclude these
);
// Disconnect client
manager.disconnect("connection-id");
// Get connection count
const count = manager.size();Custom Client Verification
webSocketServer({
verifyClient: async ({ origin, secure, req }) => {
// Check authentication
const token = req.headers["authorization"];
if (!token) return false;
try {
const user = await verifyToken(token);
return !!user;
} catch {
return false;
}
},
});Message Types
interface WSMessage<T = any> {
type: string;
data: T;
timestamp?: number;
}
interface WSConnection {
ws: WebSocket;
id: string;
metadata?: Record<string, any>;
}Configuration Options
interface WSServerOptions {
path?: string; // Default: '/ws'
handlers?: WSHandlers; // Event handlers
maxPayload?: number; // Default: 1MB
heartbeat?: boolean; // Default: true
heartbeatInterval?: number; // Default: 30000ms
verifyClient?: (info) => boolean; // Custom verification
}Examples
Check the /examples directory for:
- Basic chat application
- Real-time notifications
- Multiplayer game state sync
- Collaborative editing
Deployment
Vercel / Cloudflare / Netlify
WebSocket is not supported in serverless platforms. Use adapter-node with VPS/dedicated server.
Docker
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "server.js"]PM2
{
"apps": [
{
"name": "sveltekit-app",
"script": "server.js",
"instances": 1,
"exec_mode": "cluster"
}
]
}Troubleshooting
WebSocket not connecting in production
Make sure:
- Custom server is setup correctly
- Port has been exposed (3000 or sesuai config)
- Firewall allow WebSocket connections
- Reverse proxy (nginx) support WebSocket upgrade
Nginx Configuration
location /ws {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}Migration from Old Library
Dari ubermanu/sveltekit-websocket:
- Update dependencies
- Change plugin import dari
vite-plugin-websocketkesveltekit-ws/vite - Update handler structure (lihat docs)
- Update client code untuk use new message format
Contributing
Contributions welcome! Please read CONTRIBUTING.md.
License
MIT © 2024
Credits
Inspired by ubermanu/sveltekit-websocket
