Vite Plugin
The realtime() Vite plugin scans src/live/ and generates $live/* virtual imports.
Setup
// vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';
import uws from 'svelte-adapter-uws/vite';
import realtime from 'svelte-realtime/vite';
export default {
plugins: [sveltekit(), uws(), realtime()]
}; How it works
- The plugin watches
src/live/for.jsand.tsfiles - It parses each file for
live(),live.stream(),live.cron(), etc. exports - It generates client stub modules under the
$live/virtual import prefix live()exports become async RPC functionslive.stream()exports become Svelte store factories- Server-only code is stripped from the client bundle
What gets generated
For a file src/live/chat.js that exports:
sendMessagevialive()messagesvialive.stream()
The plugin generates $live/chat with:
sendMessage(text)- calls the server function over WebSocketmessages- a Svelte store that subscribes to the'messages'topic
File structure
src/live/
├── chat.js => $live/chat
├── todos.js => $live/todos
└── admin/
└── users.js => $live/admin/users Nested directories map to nested import paths.
Options
realtime({ dir: 'src/live', typedImports: true, devtools: true }) | Option | Default | Description |
|---|---|---|
dir | 'src/live' | Directory containing live modules |
typedImports | true | Generate .d.ts for typed $live/ imports |
devtools | true | Enable the in-browser DevTools overlay in dev mode |
When typedImports is enabled, the plugin generates type declarations that strip the ctx parameter and infer return types.
Server-side HMR
Changes to files in src/live/ are hot-reloaded on the server without restarting npm run dev. When you save a file, the plugin:
- Invalidates the changed module in Vite’s server module graph
- Clears all server-side registrations (RPC handlers, guards, cron jobs, derived streams, effects, aggregates)
- Re-imports the registry module so every registration call runs with the updated handler functions
This applies to all handler types - live(), live.stream(), live.cron(), live.derived(), live.effect(), live.aggregate(), live.room(), guard(), and everything else. Adding or deleting files in src/live/ also triggers a full re-registration.
Error recovery: if the edited file has a syntax error, the previous handlers are restored so the server keeps working. Fix the error and save again.
Active subscriptions: existing stream subscribers keep their current data and connection. They will receive new events published by the updated handler, but the init function only runs on new subscriptions. A full page reload picks up the latest init logic.
Cron jobs: old intervals are cleared and restarted with the updated schedule and handler.
Was this page helpful?