Skip to content

Svelte 5 Migration Assessment

Short Answer

Yes, the frontend could be migrated to Svelte 5, but it is a framework rewrite rather than a drop-in upgrade. The current app is a React application built on React Router, TanStack Query, React Hook Form, React Hot Toast, React Error Boundary, and React Leaflet. Those pieces do not transfer directly to Svelte, so the bulk of the work is replacing the component tree, routing, and browser state management.

If you want to reduce risk, the cleanest shape is a side-by-side app in a separate folder such as tracker-frontend-svelte/ or frontend-svelte/, with its own Vite/Svelte build and its own deployment path until parity is reached.

Because the current React frontend already runs through Docker Compose, the Svelte app should follow the same pattern: a dedicated dev container for local development and a separate production image once the new app is stable.

The Svelte app should be built for Svelte 5 only. Do not design the migration around Svelte 4 legacy syntax. Keep the codebase modular, DRY, and split into manageable components and modules instead of large monolithic page files.

What The Repo Looks Like Today

The frontend is not tiny. Under tracker-frontend/src, the codebase currently contains 56 *.tsx files and 32 *.ts files, plus tests and static assets. The main entry points are:

  • tracker-frontend/src/main.tsx
  • tracker-frontend/src/App.tsx
  • tracker-frontend/src/hooks/useAuth.ts
  • tracker-frontend/src/api/client.ts

The app already has several distinct feature areas:

  • authentication and session restoration
  • dashboard filtering, pagination, and tracker history
  • tracker map visualisation with Leaflet and marker clustering
  • location CRUD and import flows
  • campaign management and batch actions
  • reports and charts

What Can Be Reused

Several parts of the current frontend can survive the migration with little or no change:

  • backend API contracts and OpenAPI-driven type generation
  • most src/api/* request logic, if you keep the same REST endpoints
  • shared domain types in src/types/*
  • TailwindCSS design tokens and utility classes
  • Docker, nginx, and the existing deployment topology
  • pure TypeScript utility functions that do not depend on React

What Must Be Rewritten

These parts are tightly coupled to React and would need replacement:

  • routing in react-router-dom
  • React context providers and hooks such as useAuth
  • TanStack Query hooks and cache wiring
  • React Hook Form based forms
  • all React component trees in *.tsx
  • React-specific integrations such as react-leaflet
  • toast/error boundary integrations that assume React component composition

The map stack deserves special attention. Leaflet itself can stay, but the current integration uses React wrappers and React lifecycle hooks heavily. Expect to rebuild the map components rather than translate them mechanically.

That said, Leaflet is still a good fit for Svelte. Leaflet is just a JavaScript mapping library for mobile-friendly interactive maps, so the migration is mainly about replacing the React wrapper layer with Svelte components and lifecycle hooks, not replacing the map engine itself.

UI Strategy

Because the team already uses TailwindCSS, bringing in daisyUI is a sensible way to speed up the visual rewrite.

The main value is in standardizing the common shell and form patterns:

  • buttons
  • inputs
  • tabs
  • cards
  • modals
  • drawers
  • tables

That lets you convert many custom presentational components into simpler, more consistent UI primitives. It will not eliminate custom work for the map screens, dashboard filters, or dense data tables, but it should reduce the amount of bespoke CSS and improve design consistency.

daisyUI is designed to sit on top of Tailwind as a plugin, so it fits the current styling direction well.

Theme Strategy

This migration should include a real daisyUI theme system, not just a light/dark switch.

The theme switcher pattern from Cortex is a good fit here because it already solves the important parts:

  • persist the selected theme in localStorage
  • apply data-theme on the root element
  • update color-scheme so browsers render built-in controls correctly
  • fall back to the system theme when nothing is stored
  • keep the selectable theme list explicit instead of letting every page invent its own styling rules

The implementation should mirror that shape in the new Svelte app:

  • a small theme utility module
  • an early boot script in the HTML shell to avoid theme flash
  • a reusable theme selector in the app shell
  • a fixed list of supported themes, with room to expand later

That would make the Svelte rewrite materially better than the current app from a styling perspective, because it gives you a controlled design system instead of a single dark-mode toggle.

The lowest-risk path is a side-by-side migration:

  1. Keep the backend API unchanged.
  2. Stand up a new Svelte 5 frontend in a separate folder, for example tracker-frontend-svelte/.
  3. Add a matching Docker Compose service for the new app so local development still works through containers.
  4. Port shared primitives first: API client, auth/session logic, layout shell, theme handling, and Tailwind/daisyUI setup.
  5. Add the theme selector and boot-time theme application before most of the page work, so styling decisions stay consistent from the start.
  6. Port the highest-value routes next, starting with the login flow and dashboard.
  7. Move the map-heavy and form-heavy screens after the framework foundation is stable.
  8. Retire the React app only after the Svelte app reaches feature parity.

Trying to mix React and Svelte inside the same component tree is usually a dead end. It adds complexity without reducing the amount of rewrite work.

Effort Estimate

These numbers assume one experienced engineer and a requirement for functional parity with the current app.

Phase Scope Estimate
Discovery spike Validate Svelte 5, router, auth, map strategy, daisyUI fit, and container approach 2 to 4 days
Foundation Vite + Svelte 5 setup, routing, auth shell, theme system, API client, Tailwind/daisyUI, Docker dev image 1 to 2 weeks
Core pages Dashboard, trackers, locations, reports, campaigns 2 to 4 weeks
Maps and rich interactions Leaflet, clustering, editable maps, modal flows 1 to 2 weeks
Test migration and hardening Unit tests, E2E gaps, bug fixing, release validation 1 to 2 weeks

Practical total:

  • Proof of concept: 1 week or less
  • Production-ready migration with parity: 5 to 10 weeks
  • Safer estimate if requirements are still moving: 8 to 12 weeks

If two engineers can work in parallel, the calendar time can drop, but only if the work is split cleanly by route or feature area.

Main Risks

  • React-specific libraries may not have a one-to-one Svelte replacement.
  • The current auth/session flow is stateful and browser-storage heavy, so it needs careful rework.
  • Map features are the most likely source of regressions, especially around Leaflet wrappers and DOM sizing.
  • A UI refresh can expand scope quickly if there is no shared component system early.
  • Theme management can add complexity if the theme list, palette, and meta colors are not centralized.
  • Docker packaging for the new app adds setup work, but it is small compared with the framework rewrite itself.
  • Test coverage will need to be rebuilt around Svelte components and Svelte-aware utilities.
  • A framework rewrite can easily hide product scope creep, so the migration plan needs a hard feature-parity boundary.

Decision Check

Svelte 5 is a reasonable target if the goal is to reduce long-term UI complexity and you are willing to pay for a rewrite.

It is not a good choice if the goal is a cheap framework upgrade. In that case, improving the existing React app will be much faster.

If the team is already planning a visual refresh, Svelte 5 plus Tailwind plus daisyUI is a good combination for the new app shell and standard pages. It still does not remove the need to design the map-heavy screens carefully, but it should make the overall UI work more tractable.

The theme switcher is the piece that makes daisyUI especially worthwhile here. If you carry over the Cortex-style theme system, you can support multiple curated themes instead of hardcoding the app into one look and one dark mode.

Suggested Next Step

If you want, the next useful document would be a route-by-route migration plan that breaks the current frontend into:

  • reusable code
  • rewrite-required code
  • risky integrations
  • milestones for a staged cutover