Skip to content

Svelte 5 Admin Migration Assessment

Short Answer

Yes, tracker-admin can be migrated to Svelte 5 using the same side-by-side approach already used for tracker-frontendtracker-frontend-svelte. The difference this time is that a working sibling app already exists: the theme system, app shell, sidebar, API client, and auth/session logic don't need to be designed again, only ported and re-pointed at tracker-admin's own navigation and pages. What's left is a genuine framework rewrite of 12 in-scope route areas (of 14 total — the health dashboard and service controller are unused and excluded, see "Not In Scope") and roughly 22,000 lines of React, noticeably more than the frontend was.

The recommended shape is unchanged from the frontend migration: a new tracker-admin-svelte/ folder, its own Vite/SvelteKit build, its own dev container, running alongside the existing React admin panel until parity is reached.

What The Repo Looks Like Today

tracker-admin/src contains 31 page files, 51 component files, 16 hooks, and 14 API modules — roughly 22,100 lines of TypeScript/TSX in total. Entry points:

  • tracker-admin/src/App.tsx — route table (react-router-dom v6, all pages lazy-loaded)
  • tracker-admin/src/hooks/useAuth.ts — auth context
  • tracker-admin/src/api/client.ts — axios instance, token refresh, session restore
  • tracker-admin/src/components/layout/MainLayout.tsx — sidebar + mobile drawer shell

Route areas: Dashboard, Clients, Brands, Production Runs, Trackers, Locations, Images, Users, Health Dashboard, Tracker Status Heatmaps (analytics), Service Controller. Health Dashboard and Service Controller are not currently used and are out of scope for this migration — deprioritized indefinitely, not just deferred to a later phase. Five of these (clients, brands, production runs, trackers, locations) are near-identical List/Detail/Create/Edit CRUD quadruplets — the same shape repeated five times with different fields.

Two routes exist (/analytics/tracker-heatmaps, /service-controller) but are not in the sidebar nav list (MainLayout.tsx:31-38 only has 8 items: Dashboard, Clients, Brands, Production Runs, Trackers, Locations, Images, Users) — they're only reachable by typing the URL directly. This matches confirmation that Health Dashboard and Service Controller aren't in active use; no nav decision is needed since neither is being ported for now (see "Not In Scope" below).

Stray craco.config.js and webpack.config.js files exist at the tracker-admin root but appear to be dead leftovers — the app actually builds via vite.config.ts (npm run build = tsc && vite build). Worth confirming they're unused before treating them as migration input.

What Can Be Reused

Unlike the original frontend migration, this one starts with a second working example to copy from, not just a design sketch:

  • the backend API contract — same FastAPI endpoints tracker-frontend-svelte already talks to for auth (/auth/login/json, /auth/refresh-cookie, /auth/logout, /users/me), and for the domains that overlap (locations, production runs)
  • tracker-frontend-svelte's already-built, generic infrastructure: src/lib/api/client.ts, src/lib/state/auth.ts, src/lib/theme/*, src/lib/components/ThemeSelector.svelte, src/lib/utils/animatedDialog.svelte.ts — all confirmed to have no app-specific coupling during investigation, portable close to verbatim
  • tracker-frontend-svelte's locations and campaign-management components (LocationEditorModal.svelte, LocationsImportModal.svelte, CampaignEditorModal.svelte, CampaignRow.svelte, TrackerCard.svelte/TrackerListRow.svelte, MoveTrackerModal.svelte, PasteSelectModal.svelte, CampaignDeleteModal.svelte) — these are prop-driven (typed data + callbacks, no direct global-state coupling beyond LocationEditorModal/ LocationsImportModal's calls into $lib/api/locations.ts), so they're realistic to reuse directly once tracker-admin-svelte's own locations/production-runs pages exist, rather than rebuilding equivalent admin CRUD screens from scratch
  • Tailwind utility classes and pure TypeScript utilities that don't depend on React (src/utils/formatters.ts, src/utils/redirectUtils.ts)
  • Docker/nginx deployment topology, once/if this app is promoted past dev-only

What Must Be Rewritten

  • routing in react-router-dom → SvelteKit file-based routing
  • useAuth context + all use* hooks in src/hooks/ (16 files, ~2,140 lines) → Svelte stores and derived state (same pattern already proven in tracker-frontend-svelte/src/lib/state/auth.ts)
  • TanStack Query data-fetching/caching → plain $state/$derived + the shared request<T>() wrapper (no query-cache library in tracker-frontend-svelte today; decide during Foundation phase whether that's still fine at this app's scale)
  • react-hook-form-based forms → native Svelte bindings
  • all 51 src/components/* + 31 src/pages/* — no direct mechanical translation
  • @headlessui/react primitives (Dialog/Transition for the mobile sidebar drawer, modals) → daisyUI equivalents + AnimatedDialog (already used for every modal in tracker-frontend-svelte)
  • react-leaflet/leaflet-geosearch wrappers → direct Leaflet integration (same conclusion as the frontend migration: keep Leaflet itself, rebuild the wrapper layer)
  • react-hot-toast → the toast store already built for tracker-frontend-svelte ($lib/state/toast.ts — referenced by its root +layout.svelte's <ToastHost />)

Not In Scope

Health Dashboard (/health) and Service Controller (/service-controller) are not currently used and are excluded from this migration entirely, not just deferred to a later phase. That also removes chart.js/react-chartjs-2 from the rewrite list for now — Tracker Status Heatmaps is the only remaining chart-using page, and it can be revisited alongside these two if/when any of them come back into use.

Effort Estimate

This app is bigger than the frontend was, and the CRUD repetition (5 parallel List/Detail/Create/Edit sets) is the strongest signal that a shared generic list/table/form scaffold would pay for itself here more than it did in the frontend migration, where each route was more distinct.

Phase Scope Estimate
Scaffold + shared foundation Port theme/app-shell/API-client/auth verbatim, admin nav, placeholder dashboard, dev container 2 to 4 days
CRUD quadruplets Clients, brands, production runs, trackers, locations (ideally via one shared scaffold, not five) 3 to 5 weeks
Locations/campaigns reuse Wire the already-built tracker-frontend-svelte location/campaign components into admin CRUD 1 to 2 weeks
Singleton pages Images gallery, Users, Tracker Heatmaps (Health Dashboard and Service Controller excluded — unused) 1 to 2 weeks
Test migration and hardening Rebuild coverage (tracker-admin currently has 1 test file), bug fixing, release validation 1 to 2 weeks

Practical total:

  • Proof of concept (this pass — scaffold + shared foundation only): a few days
  • Production-ready migration with parity (excluding Health Dashboard/Service Controller): 7 to 11 weeks
  • Safer estimate if requirements are still moving: 10 to 14 weeks

Two engineers can parallelize by splitting along the CRUD-quadruplet boundary (one domain area each) once the shared scaffold exists, similar to the frontend's recommendation.

Main Risks

  • The CRUD repetition is also a trap: building the first quadruplet (e.g. clients) without generalizing it will make the remaining four slower, not faster. Invest in a shared list/detail/form pattern before the second quadruplet.
  • Chart.js integration (tracker heatmaps) is new territory for this codebase's Svelte side; validate the wrapper approach early, similar to how Leaflet needed its own spike in the original migration.
  • Thin test coverage (one test file in the entire current app) means there's little regression safety net — most verification will be manual, route by route.
  • Scope creep risk is higher here than it was for the frontend: an admin panel touches every entity in the system, so it's an easy place for "while we're rewriting this page" feature requests to creep in and blow the timeline.

Decision Check

This is a good target if the goal is a consistent design system (multi-theme daisyUI, shared modal/table primitives) across both the customer-facing app and the admin panel, and the team is willing to pay for a genuinely larger rewrite than the frontend was.

It is a poor target if the goal is a quick visual refresh — the existing React app already has a working (if plain) dark/light toggle, and a Svelte rewrite doesn't fix anything structurally broken in the current admin panel, it mainly buys design-system consistency with the already-migrated frontend and a smaller/simpler stack.

Given that tracker-frontend-svelte already proved out the app shell, theme system, and several reusable feature components, the marginal cost of standing up tracker-admin-svelte's foundation is now low — most of the risk and cost is concentrated in the CRUD page volume and the two precedent-free feature areas, not in re-deciding the framework/tooling questions the first migration already answered.

Suggested Next Step

See admin-svelte-implementation-plan.md for the concrete scaffold-first plan. After the scaffold lands, the next useful document is a per-quadruplet CRUD scaffold design (list/detail/form primitives shared across clients/brands/production-runs/trackers/ locations), since that decision shapes the cost of every subsequent page.