chore: prepare for 0.18.0 release

This commit is contained in:
Denis Donici 2026-03-06 13:06:04 +02:00
parent fb1e73c451
commit 084960e600
5 changed files with 304 additions and 8 deletions

View file

@ -5,11 +5,98 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
## 0.18.0 - 2026-03-06
> **Note:** Many of the features in this release were backported from
> [live_vue](https://github.com/Valian/live_vue) by
> [Jakub Skalecki](https://github.com/Valian). A huge thank you to Jakub
> for the excellent architecture and implementation that served as the
> foundation for props diffing, composables, streams support, Vite
> integration, Igniter installer, and more.
### Breaking Changes
- **esbuild removed** — LiveSvelte no longer supports esbuild. Migrate to
Vite + `phoenix_vite`. See the [Upgrade Guide](guides/upgrade_guide.html)
for step-by-step instructions.
- **live_json / live_json_props removed** — The `live_json` hex dependency
and `live_json_props` attribute have been removed. Replace with `props={...}`;
built-in JSON Patch diffing provides the same optimization by default.
- **phoenix_vite now required** — Add `{:phoenix_vite, "~> 0.4"}` to your
`mix.exs` dependencies.
### Added
- **Vite integration** — Full Vite build pipeline replaces esbuild.
`phoenix_vite` handles client and SSR builds with a single `vite.config.mjs`.
- **Vite HMR** — Hot Module Replacement for Svelte components and CSS in
development. Zero extra config when using `phoenix_vite` — just run
`mix phx.server`.
- **ViteJS SSR mode** — New `LiveSvelte.SSR.ViteJS` backend sends SSR render
requests to the Vite dev server over HTTP. New `.svelte` files are picked up
immediately without running `mix assets.build`.
- **SSR telemetry** — SSR render events emit telemetry under
`[:live_svelte, :ssr, :render, :start]` / `[:live_svelte, :ssr, :render, :stop]`
for performance monitoring.
- **Igniter installer**`mix live_svelte.install` (powered by
[Igniter](https://hex.pm/packages/igniter)) sets up LiveSvelte automatically
in an existing Phoenix project, including Vite config, endpoint changes, and
JavaScript entrypoint.
- **Props diffing (JSON Patch)** — Server-side props are diffed using RFC 6902
JSON Patch, sending only changed values to the client. Enabled by default;
disable with `config :live_svelte, enable_props_diff: false`.
- **Svelte encoder** — New `LiveSvelte.Encoder` protocol for custom JSON
serialization of Svelte props. Replaces the need for `@derive Jason.Encoder`
on Elixir structs.
- **Streams support** — Phoenix `stream/3` now works with Svelte components.
Stream operations are sent as JSON Patch ops via the `data-streams-diff`
attribute.
- **Live form support** — New `useLiveForm` composable for Ecto
changeset-backed forms in Svelte with server-side validation feedback.
- **File upload support** — New `useLiveUpload` composable for Phoenix
LiveView file uploads with progress tracking.
- **Event reply** — New `useEventReply` composable for handling `push_reply`
responses from the server.
- **Live navigation** — New `useLiveNavigation` composable exposing `patch()`
and `navigate()` for client-side routing from Svelte.
- **TypeScript rewrite** — Library source (`assets/js/live_svelte/*.ts`) is
now written in TypeScript with full type definitions exported via
`package.json`.
- **Hot-apply new components** — New `.svelte` files added during development
are automatically discovered by the ViteJS SSR mode and Vite plugin without
restarting the Phoenix server.
- **CI/CD** — GitHub Actions workflows for Elixir (tests + Coveralls coverage
reporting) and frontend (Vitest unit tests).
- **Documentation**`ex_doc` integration; all public modules now have
HexDocs entries.
- **New examples** — Drag & Drop, Rich Text Editor (Editor.js), Runed state
management, Svelte Stores.
### Removed
- **live_json** — The `live_json` hex dependency and `live_json_props` feature have been removed from the library and example project. Use built-in props diffing and JSON Patch (see Configuration) for efficient prop updates instead.
- **esbuild** — Removed `esbuild` mix dependency, `assets/build.js`, and all
related `config :esbuild` configuration.
- **live_json / live_json_props** — Removed in favor of built-in props
diffing (enabled by default).
## 0.17.4 - 2026-02-18

View file

@ -4,8 +4,9 @@ defmodule Example.MixProject do
def project do
[
app: :example,
version: "0.1.0",
elixir: "~> 1.16",
name: "LiveSvelte Example",
version: "0.18.0",
elixir: "~> 1.18",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
listeners: [Phoenix.CodeReloader],
@ -37,7 +38,7 @@ defmodule Example.MixProject do
{:gettext, "~> 0.20"},
{:json_diff_ex, "~> 0.6", override: true},
{:live_svelte, path: ".."},
# {:live_svelte, "~> 0.17.4"},
# {:live_svelte, "~> 0.18.0"},
{:phoenix, "~> 1.8.0"},
{:phoenix_ecto, "~> 4.4"},
{:phoenix_html, "~> 4.1"},

207
guides/upgrade_guide.md Normal file
View file

@ -0,0 +1,207 @@
# Upgrade Guide
## Upgrading to 0.18.0
Version 0.18.0 migrates the build toolchain from esbuild to Vite and removes
the `live_json` dependency. Follow the steps below to update your project.
### 1. Replace esbuild with Vite
#### `mix.exs` — swap deps
```elixir
# Remove:
{:esbuild, "~> 0.8", runtime: Mix.env() == :dev}
# Add:
{:phoenix_vite, "~> 0.4"}
```
Also remove any `config :esbuild` block from `config/config.exs`:
```elixir
# Remove entirely:
config :esbuild, :default,
args: ~w(js/app.js --bundle ...),
cd: Path.expand("../assets", __DIR__),
env: %{"NODE_PATH" => ...}
```
Run `mix deps.get` after updating `mix.exs`.
#### `assets/package.json` — add Vite and Svelte plugin
```json
{
"devDependencies": {
"vite": "^6.0.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tailwindcss/vite": "^4.0.0"
}
}
```
Run `npm install` (or `cd assets && npm install`) after updating.
#### Create `assets/vite.config.mjs`
Delete the old `assets/build.js` and create `assets/vite.config.mjs`:
```javascript
import { defineConfig } from "vite"
import { svelte } from "@sveltejs/vite-plugin-svelte"
import liveSveltePlugin from "live_svelte/vitePlugin"
import tailwindcss from "@tailwindcss/vite"
export default defineConfig({
server: {
host: "127.0.0.1",
port: 5173,
strictPort: true,
cors: { origin: "http://localhost:4000" },
},
optimizeDeps: {
include: ["live_svelte", "phoenix", "phoenix_html", "phoenix_live_view"],
},
ssr: { noExternal: process.env.NODE_ENV === "production" ? true : undefined },
build: {
manifest: false,
ssrManifest: false,
rollupOptions: { input: ["js/app.js", "css/app.css"] },
outDir: "../priv/static",
emptyOutDir: true,
},
plugins: [
tailwindcss(),
svelte({ compilerOptions: { css: "injected" } }),
liveSveltePlugin({ entrypoint: "./js/server.js" }),
],
})
```
The `liveSveltePlugin` is exported from `live_svelte/vitePlugin` and handles
SSR component discovery automatically — no separate SSR build config is needed.
#### Update `config/dev.exs` — replace esbuild watcher with Vite
```elixir
# Remove from watchers:
esbuild: {Esbuild, :install_and_run, [:default, ~w(--bundle ...)]}
# Update the endpoint config block:
config :my_app, MyAppWeb.Endpoint,
http: [ip: {127, 0, 0, 1}, port: 4000],
check_origin: false,
code_reloader: true,
debug_errors: true,
secret_key_base: "...",
# Assets are now served by the Vite dev server on port 5173:
static_url: [host: "localhost", port: 5173],
watchers: [
tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]},
vite: {PhoenixVite.Npm, :run, [:vite, ~w(dev)]}
]
```
Setting `static_url` to the Vite dev server port is important — it ensures
LiveView generates asset URLs that point to the Vite dev server (which provides
HMR) rather than Phoenix's static file serving.
Add ViteJS SSR for development at the bottom of `config/dev.exs`. This means
new `.svelte` files are discovered automatically without needing to rebuild assets
after every addition:
```elixir
config :live_svelte, ssr_module: LiveSvelte.SSR.ViteJS, vite_host: "http://localhost:5173"
```
Production continues to use NodeJS SSR with the pre-built `priv/svelte/server.js`
(the default), so no production config change is needed.
#### Update `lib/my_app_web/endpoint.ex`
Import `PhoenixVite.Plug` and add the favicon plug. The favicon plug proxies the
browser favicon request to the Vite dev server in development:
```elixir
defmodule MyAppWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :my_app
import PhoenixVite.Plug # <-- add this
# ... socket declarations ...
# Add before Plug.Static:
plug :favicon, dev_server: {PhoenixVite.Components, :has_vite_watcher?, [__MODULE__]}
plug Plug.Static,
at: "/",
from: :my_app,
gzip: false,
only: MyAppWeb.static_paths()
# ... rest of plugs unchanged ...
end
```
#### Update `lib/my_app_web/components/layouts/root.html.heex`
Replace the static asset tags with `PhoenixVite.Components.assets`. This single
component handles both development (proxying to the Vite dev server with HMR)
and production (emitting hashed `<script>`/`<link>` tags from the Vite manifest):
```heex
<%# Remove: %>
<link rel="stylesheet" href={~p"/assets/app.css"} />
<script defer src={~p"/assets/app.js"}></script>
<%# Replace with: %>
<PhoenixVite.Components.assets
names={["js/app.js", "css/app.css"]}
manifest={{:my_app, "priv/static/.vite/manifest.json"}}
dev_server={PhoenixVite.Components.has_vite_watcher?(MyAppWeb.Endpoint)}
to_url={fn p -> static_url(@conn, p) end}
/>
```
Replace `:my_app` and `MyAppWeb.Endpoint` with your own OTP app name and
endpoint module.
### 2. Remove live_json (if used)
Remove the dependency from `mix.exs`:
```elixir
# Remove:
{:live_json, "~> 0.4"}
```
In your LiveViews, replace the `live_json_props` attribute with the standard
`props` attribute. Props diffing via JSON Patch is enabled by default in 0.18.0,
so payloads remain optimized — only changed values are sent over the wire:
```heex
<%# Before: %>
<.svelte name="MyComponent" live_json_props={@json_props} socket={@socket} />
<%# After: %>
<.svelte name="MyComponent" props={@my_props} socket={@socket} />
```
If you want to disable props diffing globally (not recommended):
```elixir
# config/config.exs
config :live_svelte, enable_props_diff: false
```
### 3. Verify the upgrade
After completing the steps above:
```bash
mix deps.get
cd assets && npm install && cd ..
mix phx.server # Should start Phoenix + Vite dev server together
mix test # Library unit tests
cd example_project && mix assets.build && mix test --only phoenix_test
```

View file

@ -1,7 +1,7 @@
defmodule LiveSvelte.MixProject do
use Mix.Project
@version "0.17.4"
@version "0.18.0"
@repo_url "https://github.com/woutdp/live_svelte"
def project do
@ -38,6 +38,7 @@ defmodule LiveSvelte.MixProject do
# Getting Started
"guides/installation.md": [title: "Installation"],
"guides/upgrade_guide.md": [title: "Upgrade Guide"],
"guides/basic_usage.md": [title: "Basic Usage"],
# Core Usage
@ -59,7 +60,7 @@ defmodule LiveSvelte.MixProject do
"guides/troubleshooting.md": [title: "Troubleshooting"]
],
groups_for_extras: [
"Getting Started": ~r/guides\/(installation|basic_usage)/,
"Getting Started": ~r/guides\/(installation|upgrade_guide|basic_usage)/,
"Core Usage": ~r/guides\/(forms|uploads|streams|ssr|configuration)/,
Reference: ~r/guides\/api_reference/,
"Advanced Topics": ~r/guides\/(introduction|testing|deployment)/,

View file

@ -1,6 +1,6 @@
{
"name": "live_svelte",
"version": "0.17.4",
"version": "0.18.0",
"description": "",
"license": "MIT",
"types": "./assets/js/live_svelte/types.d.ts",