Skip to content

Commit 85b39fb

Browse files
committed
migration to svelte5; + docs
1 parent b12c195 commit 85b39fb

30 files changed

+1830
-1209
lines changed

docs/architecture/frontend-build.md

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ This document explains how the frontend codebase is built, what libraries are in
44

55
## Overview
66

7-
The frontend is a Svelte single-page application bundled with Rollup. It uses TypeScript for type safety, Tailwind CSS v4 for styling, and a generated SDK for type-safe API calls. The build outputs static files to `public/build/` which are served by nginx in production or by a custom HTTPS dev server during development.
7+
The frontend is a Svelte 5 single-page application bundled with Rollup. It uses TypeScript for type safety, Tailwind CSS v4 for styling, and a generated SDK for type-safe API calls. The build outputs static files to `public/build/` which are served by nginx in production or by a custom HTTPS dev server during development.
8+
9+
For details on the Svelte 5 runes API and migration patterns, see [Svelte 5 Migration](svelte5-migration.md).
810

911
```mermaid
1012
graph LR
@@ -46,14 +48,15 @@ The `rollup.config.js` file configures the entire build pipeline. It produces ES
4648

4749
### Entry point
4850

49-
The build starts from `src/main.ts`, which imports the API client setup, mounts the Svelte `App` component, and imports global CSS:
51+
The build starts from `src/main.ts`, which imports the API client setup, mounts the Svelte `App` component using Svelte 5's `mount()` function, and imports global CSS:
5052

5153
```typescript
54+
import { mount } from 'svelte';
5255
import './lib/api/setup';
5356
import App from './App.svelte';
5457
import './app.css';
5558

56-
const app = new App({
59+
const app = mount(App, {
5760
target: document.body,
5861
});
5962
```
@@ -64,7 +67,7 @@ Rollup splits the bundle into chunks to improve load performance. The `manualChu
6467

6568
| Chunk | Contents |
6669
|-------|----------|
67-
| `vendor` | Svelte, svelte-routing, axios |
70+
| `vendor` | Svelte, @mateothegreat/svelte5-router |
6871
| `codemirror` | All CodeMirror packages for the editor |
6972
| Application chunks | Route components and shared code |
7073

@@ -75,7 +78,7 @@ This means users don't re-download vendor code when application code changes, an
7578
The plugin pipeline processes files in order:
7679

7780
1. **replace** — Substitutes `process.env.VITE_BACKEND_URL` with an empty string, allowing relative API paths
78-
2. **svelte** — Compiles `.svelte` files with TypeScript preprocessing via `svelte-preprocess`
81+
2. **svelte** — Compiles `.svelte` files with TypeScript preprocessing via `svelte-preprocess`, with `runes: true` enabled for Svelte 5
7982
3. **postcss** — Processes CSS through PostCSS, extracting styles to `bundle.css`
8083
4. **typescript** — Compiles TypeScript files with source maps
8184
5. **json** — Allows importing JSON files
@@ -237,9 +240,11 @@ Styles are organized into Tailwind layers:
237240
- **base** — Element defaults, form styles, scrollbars, CodeMirror overrides
238241
- **components** — Reusable patterns like `.btn`, `.card`, `.form-input-standard`
239242

240-
## Svelte stores
243+
## Svelte stores and runes
244+
245+
The frontend uses a hybrid approach to state management:
241246

242-
Reactive state is managed through Svelte stores in `src/stores/`:
247+
**Svelte stores** (`src/stores/`) handle global, shared state:
243248

244249
| Store | Purpose |
245250
|-------|---------|
@@ -250,6 +255,30 @@ Reactive state is managed through Svelte stores in `src/stores/`:
250255

251256
Stores use the generated SDK for API calls and persist state to localStorage where appropriate. The auth store exposes a `csrfToken` store that the API client interceptor reads for request signing.
252257

258+
**Svelte 5 runes** (`$state`, `$derived`, `$effect`) handle component-local state:
259+
260+
```svelte
261+
<script lang="ts">
262+
import { isAuthenticated } from '../stores/auth';
263+
264+
// Component-local reactive state
265+
let loading = $state(false);
266+
let items = $state<Item[]>([]);
267+
268+
// Derived values
269+
let itemCount = $derived(items.length);
270+
271+
// Store subscription (unchanged from Svelte 4)
272+
// $isAuthenticated auto-subscribes to the store
273+
</script>
274+
275+
{#if $isAuthenticated}
276+
<span>Items: {itemCount}</span>
277+
{/if}
278+
```
279+
280+
For detailed patterns and migration guidance, see [Svelte 5 Migration](svelte5-migration.md).
281+
253282
## Build commands
254283

255284
| Command | Purpose |

0 commit comments

Comments
 (0)