| .. | ||
| assets | ||
| config | ||
| lib | ||
| priv | ||
| test | ||
| .formatter.exs | ||
| .gitignore | ||
| Dockerfile | ||
| mix.exs | ||
| mix.lock | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
LiveSvelte Example Project
A working Phoenix application demonstrating LiveSvelte features — Svelte 5 components
integrated with Phoenix LiveView. It uses phoenix_vite for Vite: one mix phx.server starts Phoenix and the Vite dev server, so Svelte and CSS changes hot-reload with no extra terminal.
Setup
- Install Elixir + Node.js 19+
- Run
mix setup(installs deps + npm packages + creates DB) - Start server:
mix phx.server - Visit: http://localhost:4000
Demo Categories
Basics
- Hello World (
/hello-world) — Simplest component rendering - Struct Props (
/live-struct) — Passing Elixir structs as props (requires@derive Jason.Encoder) - Lodash (
/lodash) — Using npm packages in Svelte components
Interactive
- Counter (
/live-simple-counter) — Server state + client events - Plus/Minus (Live) (
/live-plus-minus) — LiveView event handling - Hybrid Counter (
/live-plus-minus-hybrid) — Mix of client and server events - Lights (
/live-lights) — Multiple components sharing LiveView state - Sigil (
/live-sigil) — Inline Svelte templates with the~Vsigil
Data & Real-Time
- Streams (
/streams) — Phoenixstream()for efficient list updates - Props Diff (
/live-props-diff) — Only changed assigns sent on update (JSON Patch) - ID List Diff (
/live-id-list-diff) — ID-based list diffing for minimal ops - Chat (
/live-chat) — Real-time updates with PubSub +pushEvent - Log List (
/live-log-list) — Dynamic list updates - Breaking News (
/live-breaking-news) — Real-time ticker with~Vsigil
Slots
- Simple Slots (
/live-slots-simple) — Basic slot usage - Dynamic Slots (
/live-slots-dynamic) — Named slots with dynamic content
Composables
- Form (
/live-form) —useLiveForm()with Ecto changeset validation - File Upload (
/live-upload) —useLiveUpload()with progress and validation - Navigation (
/live-navigation) —useLiveNavigation()for patch/navigate - Composition (
/live-composition) —useLiveSvelte()for pushEvent in component trees - Event Reply (
/live-event-reply) —useEventReply()for request-response
Advanced
- SSR Demo (
/live-ssr) — Server-side rendering with NodeJS (see SSR section below) - Client Loading (
/live-client-side-loading) — Loading slot shown until hydration
Ecto
- Notes OTP (
/live-notes-otp) — SQLite-backed notes with Ecto
Testing
# Server-side tests (fast, no browser)
mix test --only phoenix_test
# Browser E2E tests (requires ChromeDriver)
mix test --only e2e
# All tests
mix test
After changing JS/Svelte files, rebuild before running tests:
mix assets.build && mix test
E2E tests require Chrome + ChromeDriver in PATH. Install with your OS package manager.
See live_svelte/CLAUDE.md for detailed testing guidance.
SSR (Server-Side Rendering)
In development the app uses LiveSvelte.SSR.ViteJS: SSR requests go to the Vite dev server (started by the :vite watcher in config/dev.exs). The endpoint’s static_url and watchers are set so that assets and HMR are served from Vite.
config/dev.exs (already set in this project):
config :live_svelte, ssr_module: LiveSvelte.SSR.ViteJS, vite_host: "http://localhost:5173"
# Endpoint also has static_url: [host: "localhost", port: 5173] and watchers: [..., vite: {PhoenixVite.Npm, :run, [:vite, ~w(dev)]}]
For production, NodeJS SSR is used (already configured); build the SSR bundle with:
mix assets.build && mix compile
The SSR demo page (/live-ssr) uses ssr={true} on the component. NodeJS must be available for SSR in production; in test env SSR is disabled globally via config :live_svelte, ssr: false.
Learn more
- LiveSvelte: https://github.com/woutdp/live_svelte
- Phoenix: https://hexdocs.pm/phoenix