6.6 KiB
React Runtime Migration Design
Context
The current Dimension Lab website is a SvelteKit application. It uses Bun, Vite, Svelte 5, SvelteKit server routes, Svelte Storybook stories, and Svelte SSR component tests. The app has one dashboard route, one agent configuration API route, reusable Svelte UI components, typed dashboard model data, Drizzle-backed SQLite persistence, datasource resolution, Playwright desktop/mobile checks, and a Bun-based container runtime.
The migration goal is to make the project React-based so dashboard UI components can be reused outside the current app. A partial React island inside SvelteKit would leave the app split across two component systems, so the target state is a React runtime and React component library.
Target Architecture
Use Vite React for the browser app and a small Bun HTTP server for production runtime. This keeps the existing Bun SQLite persistence model and avoids adding a heavier React framework where the current route/API surface is small.
The migrated app will have these boundaries:
src/main.tsxmounts the React application in the browser.src/App.tsxowns dashboard loading, refresh timing, document-to-UI mapping, and non-ready dashboard states.src/server/index.tsserves the Vite build output in production and exposes JSON API routes.src/server/routes/dashboard.tsloads the dashboard runtime and resolves live datasources unlessDISABLE_LIVE_DATASOURCES=1.src/server/routes/agent-dashboard.tsdelegates POST requests to the existinghandleAgentDashboardRequestfunction.src/lib/model/**,src/lib/server/db/**,src/lib/server/dashboard.ts,src/lib/server/datasources/**, andsrc/lib/server/agent-config/**remain TypeScript business logic with minimal import-path updates.src/lib/ui/components/*.tsxcontains the reusable React component library.src/lib/ui/stories/*.stories.tsxcontains React Storybook stories.
Component Migration
Every current Svelte UI component will be ported to React with typed props:
- Badge
- Button
- CornerBracketFrame
- DashboardFrame
- DashboardHeader
- DiagonalStripeField
- FooterCell
- FooterStatusCell
- GridFrame
- IconButton
- IconGlyph
- LineChart
- ModuleCard
- Panel
- ProgressMeter
- ScanlineField
- Separator
- ServiceGroupPanel
- ServicePanel
- ServiceRow
- SignalTrace
- Sparkline
- StatusBadge
- StatusStrip
- SystemState
- TelemetryCard
- TelemetryGrid
- TelemetryStrip
- WeatherModule
The visual design, CSS custom property tokens, accessibility attributes, data-model identifiers, severity attributes, focusable links, reduced-motion behavior, and screenshot-tested dashboard layout must stay equivalent to the current Svelte implementation.
CSS will remain in src/lib/ui/tokens.css and component-specific CSS files.
React components should import their own CSS modules or regular CSS files in a
consistent local pattern. Shared UI types and dashboardDocumentToUiDashboard
remain framework-agnostic TypeScript.
Runtime And API Behavior
The React app will fetch GET /api/dashboard on page load. When the runtime
state is ready, the response includes the dashboard document and metadata. When
the runtime state is empty, loading, or invalid, the React app renders the same
state shell that the Svelte page currently renders.
Ready dashboard documents use metadata.refreshIntervalSeconds to schedule a
refresh. The React implementation will clear old timers when the dashboard
state changes and on unmount.
The existing agent configuration endpoint remains available at
POST /api/agent/dashboard. The request validation, token authorization,
preview, publish, rollback, JSON patch behavior, and persistence behavior remain
owned by src/lib/server/agent-config/index.ts.
Build, Storybook, And Deployment
package.json will move from Svelte/SvelteKit dependencies to React tooling:
- Runtime dependencies include
@vitejs/plugin-react,react,react-dom,@iconify/react, and existing non-Svelte libraries that still apply. - Storybook moves from
@storybook/sveltekitand Svelte CSF to@storybook/react-vite. svelte.config.js,src/app.html,src/routes/**, and.sveltefiles are removed after equivalent React/server files exist.
The production build still creates build/index.js as the Bun server entry so
the current container command remains:
DATABASE_URL=file:/data/dimensionlab.sqlite HOST=0.0.0.0 PORT=3000 bun build/index.js
The Containerfile continues to install with Bun, build with Bun, copy the
client/server build output plus drizzle/, and run the Bun server.
Testing Strategy
The migration is verified with equivalent or stronger tests:
- TypeScript check covers React TSX, server modules, and shared model code.
- Current model, validation, database, datasource, and agent-config unit tests remain in place.
- Svelte SSR component tests become React
react-dom/servertests. - Page rendering tests become React app/server response tests.
- Storybook boundary tests are updated to require React story files and continue preventing Dimension Lab-specific content in reusable presentation stories.
- Playwright desktop/mobile tests continue to run against the production Bun server and the built React app.
- The full QA gate remains
bun run test:qa.
Completion Criteria
The migration is complete only when current evidence proves all of these:
- There are no
.svelteapp, component, route, or story files left. package.jsonhas no Svelte, SvelteKit, or Svelte Storybook dependencies.bun run checkpasses.bun run test:unitpasses.bun run buildproduces the React client build and Bun server entry.bun run build-storybookpasses with React stories.bun run test:e2epasses on desktop and mobile.- The dashboard renders from the same validated dashboard model data.
POST /api/agent/dashboardstill exercises the existing agent config logic.- The production container still runs with
bun build/index.js.
Migration Approach
The work should be implemented in focused commits on codex/react-migration:
- Establish React/Vite/Bun server scaffolding and tests while keeping the current Svelte code available for reference.
- Port reusable UI components to React and update render tests.
- Port the dashboard app route and refresh behavior to React.
- Port Storybook stories and presentation boundary tests to React.
- Remove SvelteKit runtime files and dependencies.
- Update build, e2e, README, and container behavior.
- Run the full QA gate, push the branch, open a ready PR, perform independent review, fix blockers, and merge only after checks and review pass.