Quick Start
One command. Full project. Working realtime.
npx svelte-realtime my-app
cd my-app
npm run dev Open your browser. Click the button. Open a second tab. Click again. Both tabs update.
Requirements
svelte-realtime runs on any environment that supports long-lived Node.js processes - VPS, containers, Docker, bare metal. It uses uWebSockets.js for native WebSocket performance, which means it needs a persistent server process. It does not run on serverless platforms (Vercel, Cloudflare Workers, Netlify Functions) or edge runtimes. This is a deliberate architectural choice, not a limitation - native WebSocket connections require a long-lived process.
Runtime floor: Node.js 22+, @sveltejs/kit ^2.0.0. Redis 7.4+ is required only if you use the extensions package for cluster-grade features (presence, replay, sharded bus, function library, etc.) - core svelte-realtime + svelte-adapter-uws need no Redis at all.
Version compatibility
The three ecosystem packages move together. Bump them as a group:
svelte-adapter-uws | svelte-realtime | svelte-adapter-uws-extensions | Notes |
|---|---|---|---|
^0.4.x | ^0.4.x | ^0.4.x | Legacy stable |
^0.5.0 | ^0.5.0 | ^0.5.0 | Current. Bump all three together. See Upgrade Quickstart if upgrading from 0.4. |
Mixed-version installs are rejected at install time with a peer-dep warning. Pinning across the boundary is not supported.
What just happened
The CLI scaffolded a SvelteKit project with everything wired:
svelte.config.js- adapter set tosvelte-adapter-uwsvite.config.js-sveltekit(),uws(), andrealtime()pluginssrc/hooks.ws.ts- WebSocket upgrade and message handlersrc/live/counter.ts- a workinglive()RPC +live.stream()src/routes/+page.svelte- imports from$live/counterand renders it
Replacing the scaffold auth placeholder
The scaffolded src/hooks.ws.ts ships with a permissive upgrade() that returns a fresh UUID for every connection, so the first npm run dev works without any identity wiring. The placeholder is intentional - it keeps the zero-config path intact - but it must be replaced before deploying.
The scaffold makes the replacement explicit. A const SCAFFOLD_PLACEHOLDER = true; line at the top of the file triggers a per-connection console.warn until you delete it:
[svelte-realtime] Default scaffold upgrade() is still active. Each connection
is getting a random anonymous identity. Replace upgrade() in src/hooks.ws.ts
with real authentication and delete the SCAFFOLD_PLACEHOLDER marker. Dev terminals see the warning on every connection; production log aggregators get unmissable noise. The marker has to be deleted from source code - a comment edit will not silence it - so the “I have replaced this with real auth” action is explicit and cannot be skipped by accident.
The scaffolded file lists three concrete patterns to copy from. Pick one:
Cookie-validated session
// src/hooks.ws.ts
import type { UpgradeHandler } from 'svelte-realtime/server';
import { validateSession } from '$lib/server/auth';
export const upgrade: UpgradeHandler = ({ cookies }) => {
const session = validateSession(cookies.session_id);
if (!session) return false;
return { id: session.userId, name: session.name };
}; JWT / bearer token
import { verifyJwt } from '$lib/server/jwt';
export const upgrade: UpgradeHandler = ({ getHeader }) => {
const auth = getHeader('authorization');
if (!auth?.startsWith('Bearer ')) return false;
const claims = verifyJwt(auth.slice(7));
if (!claims) return false;
return { id: claims.sub, role: claims.role };
}; Signed query-string token
import { verifyQueryToken } from '$lib/server/auth';
export const upgrade: UpgradeHandler = ({ url }) => {
const claims = verifyQueryToken(url.searchParams.get('t'));
if (!claims) return false;
return { id: claims.userId };
}; After replacing upgrade(), delete the SCAFFOLD_PLACEHOLDER line. See Auth for the full set of authorization building blocks and Authorization model for the trust contract.
Templates
Three templates are available:
| Template | What you get |
|---|---|
minimal (default) | Just the wiring - SvelteKit + svelte-realtime, no example code |
example | Working counter - open two tabs, click, both update |
demo | Clones the full svelte-realtime-demo app |
npx svelte-realtime my-app --template minimal
npx svelte-realtime my-app --template demo Package manager detection
The CLI detects your preferred package manager. If you run it with pnpm dlx, it uses pnpm. Same for yarn and bun.
Next steps
- Tutorial - 24 interactive lessons, write real code in the browser
- Manual setup - add svelte-realtime to an existing project
- RPC - how
live()works - Streams - how
live.stream()works
Was this page helpful?