Skip to content

chore: Remove SvelteKit, modernise frontend to Svelte 5 + Vite#427

Merged
hhvrc merged 8 commits intodevelopfrom
chore/update-frontend
Mar 6, 2026
Merged

chore: Remove SvelteKit, modernise frontend to Svelte 5 + Vite#427
hhvrc merged 8 commits intodevelopfrom
chore/update-frontend

Conversation

@hhvrc
Copy link
Contributor

@hhvrc hhvrc commented Mar 6, 2026

The captive portal frontend used SvelteKit as a build tool only - none of its server-side features (SSR, routing, load functions, form actions, API routes) were in use. The entire app is a single-page, purely client-side WebSocket UI served statically from ESP32 LittleFS. This PR removes SvelteKit entirely and replaces it with plain Svelte 5 + Vite, then modernises all state management to native Svelte 5 runes.

Bundle impact

Before After Δ
index.html raw 407 kB 363 kB −44 kB (−11%)
index.html gzipped 114 kB 100 kB −14 kB (−13%)
Production build time ~18.7 s ~8.0 s −57%

Dependency changes

Removed:

  • @sveltejs/kit
  • @sveltejs/adapter-static

Added:

  • vite-plugin-singlefile - replaces bundleStrategy: 'inline' from the old adapter, inlining all JS/CSS into a single index.html (required for LittleFS)

Updated:

  • @sveltejs/vite-plugin-svelte ^5^6

Structural changes

Before After
src/routes/+layout.svelte + +page.svelte src/App.svelte
src/app.html (SvelteKit template) index.html (Vite standard)
src/main.ts (implicit SvelteKit entry) src/main.ts using mount()
svelte.config.js with adapter-static kit config svelte.config.js with compiler options only
tsconfig.json extending .svelte-kit/tsconfig.json Self-contained tsconfig.json with explicit $lib paths
svelte-kit sync in prepare/check scripts Removed

Store modernisation (Svelte 4 → Svelte 5)

All stores migrated from svelte/store writable/subscribe pattern to Svelte 5 $state / $derived rune classes:

  • HubStateStore.tsHubStateStore.svelte.ts - $state fields per property; wifiNetworkGroups is now $derived.by from wifiNetworks (was manually recomputed after every mutation); exported as hubState instance
  • UsedPinsStore.tsUsedPinsStore.svelte.ts - private $state Map with typed accessor; exported as usedPins instance
  • ColorSchemeStore.tsColorSchemeStore.svelte.ts - existing $state class, removed browser SSR guard (always runs in browser)
  • All $HubStateStore.x / $UsedPinsStore.x template subscriptions replaced with plain hubState.x / usedPins.x
  • HubStateStore.update((s) => { ... }) batch mutation pattern replaced with direct property assignment

Other cleanup

  • WebSocketClient: removed $app/environment (browser) guard and $app/stores (page) import - replaced with window.location.hostname
  • Header.svelte: removed data-sveltekit-preload-data="hover" attribute
  • app.d.ts: removed empty SvelteKit App namespace
  • eslint.config.js: removed svelte/no-navigation-without-resolve (SvelteKit-only rule)
  • pnpm-lock.yaml: overrides for cookie and js-yaml (SvelteKit transitive deps) removed

@hhvrc hhvrc requested review from LucHeart and Copilot March 6, 2026 11:58
@hhvrc hhvrc self-assigned this Mar 6, 2026
@github-project-automation github-project-automation bot moved this to Todo in Roadmap Mar 6, 2026
@changeset-bot
Copy link

changeset-bot bot commented Mar 6, 2026

⚠️ No Changeset found

Latest commit: 16654a5

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the SvelteKit framework from the captive portal frontend (which never used SSR or routing features) and replaces it with plain Svelte 5 + Vite. The build output is a single index.html inlined via vite-plugin-singlefile for serving from ESP32 LittleFS. All state management is modernized from Svelte 4 writable stores to Svelte 5 $state/$derived rune classes, and shadcn-svelte UI components are upgraded to newer versions compatible with bits-ui v2.

Changes:

  • Replaced SvelteKit with plain Svelte 5 + Vite, moving the app entry from src/routes/+layout.svelte + +page.svelte to src/App.svelte + src/main.ts, and updating all build/config files accordingly.
  • Migrated all stores (HubStateStore, UsedPinsStore, ColorSchemeStore) from svelte/store writables to Svelte 5 $state/$derived rune classes in .svelte.ts files, replacing all $store subscriptions with direct property access.
  • Upgraded shadcn-svelte UI components (dialog, dropdown-menu, button, input, label, scroll-area, sonner) to newer patterns—moved utility types from bits-ui to $lib/utils/shadcn.ts, added data-slot attributes, and updated Tailwind CSS from v3 HSL variable theme to v4 OKLCH inline theme.

Reviewed changes

Copilot reviewed 86 out of 88 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
frontend/vite.config.ts Replaced SvelteKit plugin with standalone Svelte/Vite config, added singlefile, license, and visualizer plugins
frontend/tsconfig.json Self-contained config with explicit $lib path alias, removing SvelteKit extends
frontend/tailwind.config.ts Deleted — theme config moved to app.css using Tailwind v4 syntax
frontend/svelte.config.js Stripped SvelteKit adapter/kit config; kept compiler options for runes mode
frontend/src/routes/* Deleted all SvelteKit route files
frontend/src/main.ts New Vite entry point using Svelte mount()
frontend/src/App.svelte Consolidated layout + page into single root component
frontend/src/lib/stores/*.svelte.ts Migrated all stores to Svelte 5 $state/$derived rune classes
frontend/src/lib/WebSocketClient.ts Removed $app/environment and $app/stores imports
frontend/src/lib/MessageHandlers/index.ts Updated all store references from HubStateStore methods to direct hubState property access
frontend/src/lib/MessageHandlers/WifiNetworkEventHandler.ts Same store reference updates
frontend/src/lib/components/*.svelte Updated store access patterns from $HubStateStore.x to hubState.x
frontend/src/lib/components/LightSwitch.svelte Updated to use ColorScheme enum and colorScheme instance
frontend/src/lib/utils/shadcn.ts New file hosting cn() and utility types moved from bits-ui
frontend/src/lib/typeguards/ Renamed from type_guards, added isBoolean, isDate, isStringOrNull
frontend/src/app.css Replaced HSL variables with OKLCH values, Tailwind v4 @theme inline syntax
frontend/src/app.d.ts Replaced SvelteKit App namespace with Navigator and ObjectConstructor augmentations
frontend/index.html Standard Vite HTML entry replacing SvelteKit template placeholders
frontend/src/lib/components/ui/** Updated shadcn-svelte components with data-slot attributes, new import paths
frontend/package.json Removed SvelteKit dependencies, added new plugins, updated all versions
frontend/eslint.config.js Updated for flat config with defineConfig, removed SvelteKit-specific rules
frontend/components.json Updated shadcn-svelte registry and utility paths
frontend/.prettierrc Added prettier-plugin-organize-imports
frontend/playwright.config.ts Updated to use pnpm, added reporter and trace config
frontend/src/lib/Serializers/*.ts Import reordering only

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@hhvrc hhvrc merged commit 5f88638 into develop Mar 6, 2026
36 checks passed
@github-project-automation github-project-automation bot moved this from Todo to Done in Roadmap Mar 6, 2026
@hhvrc hhvrc deleted the chore/update-frontend branch March 6, 2026 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants