Skip to content

Modernize the dashboard frontend: framework port with decision matrix (server-first, BFF, predictive prefetch) #1608

Description

@Xore

Per Xore: not simply a React port — research decides the stack. The all-client SPA pattern is legacy (react-2026, dev.to/pritampatil); the dashboard moves to a modern server-first frontend while the design and feel stay exactly the same (improvements and modern techniques allowed, no legacy patterns). Backend workers stay Go (or a demonstrably faster language where clearly justified).

Use-case profile (what the matrix scores against)

  • Self-hosted, single-operator deployment (docker compose on the homeserver; today a single Go binary with embedded UI)
  • Strict CSP with per-request nonces; no third-party origins
  • Live data: SSE stream + periodic in-place refresh; ES-backed pagination ("View more" + skeleton-first is a hard rule)
  • Keycloak OIDC (server-side session, redis-backed)
  • Heavy data-table/inspector UI (master-detail closed-by-default everywhere), Leaflet map, ECharts/cytoscape islands
  • Design: claude-pure element set from Xore/theme — must port 1:1

New architecture (per Xore)

frontend → frontend-backend (BFF) → Go backend → ES storage. The framework's Node server IS the BFF: it owns session-aware data composition, per-route aggregation, and the predictive-prefetch brain; the Go dashboard backend keeps ES access, workers, and existing APIs (trimmed to a service API).

Required feature: predictive prefetching (toggleable)

Server Components (or the framework's closest server-side equivalent) that anticipate the likely next click and prefetch that route's payload — seeded with static heuristics (sidebar order, master-detail row → inspector, campaign → investigate) and optionally a learned model later (cf. intelligent prefetching with TF.js, Next.js prefetching guide). Must ship behind a settings toggle (default on, one click off when buggy) — same prefs mechanism as theme/palette.

Candidates researched (Aug 2026)

Sources: Platformatic SSR benchmark, TanStack Start vs Next.js 2026, Astro vs Next vs TanStack, RR7 vs TanStack vs Next, Procedure: Next vs RR7 vs Astro.

Criterion (weight) Next.js 15/16 (App Router, RSC) React Router 7 (framework mode) TanStack Start 1.x Astro 6 (+ React islands)
Server-first / RSC (15%) 5 — real Server Components, PPR 3 — loaders/actions; RSC support early 3 — server functions, no full RSC 4 — zero-JS default, islands
Predictive prefetch machinery (15%) 5 — segment-level RSC prefetch cache built in 3 — route/link prefetch, custom brain needed 4 — router preloading + typed loaders, custom brain 2 — page-level prefetch only
Self-host simplicity (12%) 3 — standalone Node server, heavier build 5 — plain Node/Express-able server 4 — Nitro/Vite server, lean 4 — node adapter
Strict CSP + nonces (10%) 3 — supported but RSC/inline quirks 5 — you own the server & headers 4 4
Live SSE + dashboard interactivity (12%) 4 4 5 — client-first model fits data-heavy UI 3 — islands make app-wide live state harder
Type safety end-to-end (8%) 3 4 5 — best-typed router in 2026 3
Raw SSR throughput (8%) 3 4 5 (benchmark winner) 4
BFF fit (10%) 4 — route handlers + RSC 4 — loaders/actions = natural BFF 4 — server functions 3
Maturity/ecosystem (5%) 5 (60–70% adoption) 4 3 — 1.x stable early 2026, momentum 4
1:1 design port effort (5%) 4 4 4 3 — islands refactor cost
Weighted total 3.9 4.0 4.2 3.3

Recommendation ("best of all of them")

  • Base: TanStack Start — best fit for a data-heavy interactive dashboard, best TS, fastest SSR, lean self-host server that doubles as the BFF.
  • Adopt from RR7: web-standards data patterns (loader/action semantics) where TanStack allows.
  • Adopt from Next.js: the segment-prefetch idea — implemented in our BFF as a predictive prefetch service (server-side route-payload cache + ``/router.preload driven by the heuristics above), since full RSC is Next-only today. If, at kick-off, first-class Server Components are judged non-negotiable, Next.js standalone is the fallback winner (accepting heavier self-hosting + CSP care).
  • Adopt from Astro: ship-zero-JS discipline — islands thinking for the chart/map embeds.
  • Final call re-validated at implementation kick-off against then-current releases (RR7 RSC support may have matured).

Scope checklist

  • Scaffold framework app + BFF layer (Node) beside the Go backend; Go API trimmed to service endpoints
  • Port Xore/theme tokens/components 1:1 (no visual drift; palettes/theme/prefs keep working)
  • SSE live stream, View-more + skeleton-first, master-detail inspector, SPA-feel navigation
  • Predictive prefetching behind a settings toggle
  • Keycloak OIDC on the BFF; strict CSP + nonces preserved
  • compose service + Traefik wiring; deploy via Arcane
  • Afterwards (separate issue): full ES-store coverage audit implemented directly into the BFF

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions