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-uwssvelte-realtimesvelte-adapter-uws-extensionsNotes
^0.4.x^0.4.x^0.4.xLegacy stable
^0.5.0^0.5.0^0.5.0Current. 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 to svelte-adapter-uws
  • vite.config.js - sveltekit(), uws(), and realtime() plugins
  • src/hooks.ws.ts - WebSocket upgrade and message handler
  • src/live/counter.ts - a working live() RPC + live.stream()
  • src/routes/+page.svelte - imports from $live/counter and 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:

// 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:

TemplateWhat you get
minimal (default)Just the wiring - SvelteKit + svelte-realtime, no example code
exampleWorking counter - open two tabs, click, both update
demoClones 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?