feat(frontend): migrate from React to Svelte 5 - #86
Merged
Conversation
Replace all React/.tsx components, hooks, and routes with Svelte 5 equivalents per ADR-023. Removes react, @tanstack/react-router, @copilotkit/react-core, @ag-ui/core and all related packages. Adds svelte@5, @sveltejs/vite-plugin-svelte, eslint-plugin-svelte, svelte-eslint-parser, and @testing-library/svelte. - Replace App.tsx/main.tsx with App.svelte/main.ts - Replace all components/chat/*.tsx with .svelte equivalents - Add new components: AttachmentGroup, ReasoningGroup, ToolCallCard, ToolGroup, TurnFooter (extracted from ChatTranscript/ChatComposer) - Add components/settings: BackendCard, HistorySourceCard - Replace useAgUiChat.ts (971 lines) with chatStore.svelte.ts using Svelte 5 runes — eliminates stale-closure ref workarounds - Replace useBackendSettings.ts with backendStore.svelte.ts - Replace TanStack Router with minimal hash-based Svelte-native router - Replace routes/chat.tsx + routes/settings.tsx with ChatPage.svelte, ChatLayout.svelte, SettingsPage.svelte - Add stream-events.ts replacing @ag-ui/core string constants - Replace react-markdown/react-syntax-highlighter with marked+highlight.js - Update eslint.config.mjs: remove react-hooks/react-refresh, add eslint-plugin-svelte with flat config - Update vite.config.ts and vitest.config.ts for Svelte plugin - All 262 tests pass, lint clean, typecheck clean, zero compiler warnings closes #79
There was a problem hiding this comment.
Pull request overview
This PR migrates the frontend UI layer from React/TanStack Router to Svelte 5, updates tooling (Vite/Vitest/ESLint/Storybook) accordingly, and replaces AG-UI/CopilotKit dependencies with local equivalents to keep SSE handling stable.
Changes:
- Replaces React entrypoints, routing, components, and hooks with Svelte 5
.sveltecomponents and rune-based stores. - Updates build/test/tooling configs for Svelte (Vite, Vitest projects, ESLint flat config, Storybook Svelte).
- Introduces local
StreamEventconstants to replace@ag-ui/coreevent types.
Reviewed changes
Copilot reviewed 68 out of 69 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| vitest.config.ts | Switches Vitest to Svelte plugin + happy-dom and splits into backend/frontend projects. |
| vite.config.ts | Replaces React plugin with Svelte plugin and keeps Tailwind integration. |
| package.json | Removes React/TanStack/AG-UI deps; adds Svelte, Svelte tooling, and markdown/highlighting deps. |
| frontend/tsconfig.json | Adjusts TS config for Svelte types and bundler module resolution. |
| frontend/src/stream-events.ts | Adds local SSE event constants to mirror backend events. |
| frontend/src/store/backendStore.svelte.ts | Adds Svelte rune-based stores for backend + history-source settings. |
| frontend/src/routes/SettingsPage.svelte | Adds Svelte settings page wiring the new stores into UI. |
| frontend/src/routes/ChatLayout.svelte | Adds a Svelte layout page used for Storybook/demo layout composition. |
| frontend/src/routes/chat.test.svelte.ts | Migrates chat route tests from React Testing Library to Svelte Testing Library and hash routing. |
| frontend/src/routes/chat-layout.stories.tsx | Removes the React Storybook story for ChatLayout. |
| frontend/src/routes/chat-layout.stories.ts | Adds Svelte Storybook stories for ChatLayout. |
| frontend/src/router.ts | Removes TanStack Router setup. |
| frontend/src/router.test.svelte.ts | Updates router behavior tests for hash-based routing in Svelte app shell. |
| frontend/src/main.tsx | Removes React root render entry. |
| frontend/src/main.ts | Adds Svelte mount() entrypoint. |
| frontend/src/hooks/useBackendSettings.ts | Removes the React backend/history settings hooks (replaced by stores). |
| frontend/src/components/settings/HistorySourceCard.svelte | Adds Svelte UI card for editing history source config. |
| frontend/src/components/settings/BackendCard.svelte | Adds Svelte UI card for editing backend config + discovered history sources. |
| frontend/src/components/chat/TurnFooter.svelte | Adds Svelte turn footer rendering patch/file summaries and patch diff loading UI. |
| frontend/src/components/chat/ToolGroup.svelte | Adds Svelte tool/action block grouping and rendering. |
| frontend/src/components/chat/ToolCallCard.svelte | Adds Svelte tool call rendering with summarized args/result display. |
| frontend/src/components/chat/StructuredAssistantMessage.test.svelte.ts | Migrates structured message tests to Svelte Testing Library. |
| frontend/src/components/chat/StructuredAssistantMessage.svelte | Adds Svelte structured assistant message grouping (reasoning/tools/attachments/notices). |
| frontend/src/components/chat/SessionList.tsx | Removes React SessionList component. |
| frontend/src/components/chat/SessionList.svelte | Adds Svelte SessionList component. |
| frontend/src/components/chat/SessionList.stories.tsx | Removes React SessionList stories. |
| frontend/src/components/chat/ReasoningGroup.svelte | Adds Svelte reasoning block UI with markdown rendering. |
| frontend/src/components/chat/ProjectWorkspacePanel.tsx | Removes React workspace panel. |
| frontend/src/components/chat/ProjectWorkspacePanel.test.svelte.ts | Migrates workspace panel tests to Svelte Testing Library. |
| frontend/src/components/chat/ProjectWorkspacePanel.svelte | Adds Svelte workspace panel UI (project picker + explorer). |
| frontend/src/components/chat/ProjectContextSwitcher.test.svelte.ts | Migrates context switcher tests to Svelte Testing Library/event model. |
| frontend/src/components/chat/icons/AgentIcon.tsx | Removes React agent icon component. |
| frontend/src/components/chat/icons/AgentIcon.svelte | Adds Svelte agent icon component. |
| frontend/src/components/chat/ChatWelcomeState.tsx | Removes React welcome state component. |
| frontend/src/components/chat/ChatWelcomeState.test.svelte.ts | Migrates welcome state tests to Svelte Testing Library. |
| frontend/src/components/chat/ChatWelcomeState.svelte | Adds Svelte welcome state component. |
| frontend/src/components/chat/ChatTranscriptA2UIDisabled.test.svelte.ts | Updates A2UI-disabled transcript test to Svelte component import. |
| frontend/src/components/chat/ChatTranscript.test.svelte.ts | Migrates transcript tests to Svelte Testing Library. |
| frontend/src/components/chat/ChatTranscript.stories.tsx | Removes React transcript stories. |
| frontend/src/components/chat/ChatTranscript.stories.ts | Adds Svelte transcript stories. |
| frontend/src/components/chat/ChatHeader.tsx | Removes React header component. |
| frontend/src/components/chat/ChatHeader.test.svelte.ts | Migrates header tests to Svelte Testing Library. |
| frontend/src/components/chat/ChatHeader.svelte | Adds Svelte header component with hash-based settings links. |
| frontend/src/components/chat/ChatHeader.stories.ts | Updates header stories for Svelte Storybook. |
| frontend/src/components/chat/ChatDiffView.tsx | Removes React diff view component. |
| frontend/src/components/chat/ChatDiffView.test.svelte.ts | Migrates diff view tests to Svelte Testing Library. |
| frontend/src/components/chat/ChatDiffView.svelte | Adds Svelte diff view component. |
| frontend/src/components/chat/ChatComposer.tsx | Removes React composer component. |
| frontend/src/components/chat/ChatComposer.stories.tsx | Removes React composer stories. |
| frontend/src/components/chat/AttachmentGroup.svelte | Adds Svelte attachment/image viewer component. |
| frontend/src/components/chat/_innerWidth.test.svelte.ts | Adds a happy-dom environment sanity test. |
| frontend/src/App.tsx | Removes React App router provider. |
| frontend/src/App.svelte | Adds Svelte app shell with hash-based route switching. |
| frontend/index.html | Points the HTML entry at the new Svelte main. |
| eslint.config.mjs | Switches ESLint config from React plugins to Svelte plugin + parser. |
| .storybook/preview.ts | Updates Storybook preview typing for Svelte-Vite framework. |
| .storybook/main.ts | Switches Storybook framework to Svelte-Vite and updates story globs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- (#87) Remove legacy /load path; unify history continuation on /resume - (#88) Guard SSE connection to live sessions only (bootstrap-safe) - (#89) Split settings IA: read-only agents section, editable history sources - (#90) Add GET /api/history-sources/status endpoint and discovery UI - (#91) Source-aware session list/header semantics for history vs live - (#92) Remove auto-live-session creation on project switch closes #87 closes #88 closes #89 closes #90 closes #91 closes #92
- Use agentStatusLabel() for aria-label on agent status dot in SessionList - Sanitize marked.parse() output with DOMPurify in ChatTranscript and ReasoningGroup - Add dialog role, aria-modal, tabindex, Escape key handling, and focus management to AttachmentGroup image viewer - Remove trivial _innerWidth.test.svelte.ts (noise, no real assertion) - Add missing storybook CLI devDependency so build:storybook works
- Replace @playwright/experimental-ct-react with @playwright/experimental-ct-svelte - Rewrite playwright-ct.config.ts to use @sveltejs/vite-plugin-svelte - Rewrite chat-surfaces.spec.ts to mount .svelte components with correct props
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
.tsx) components, hooks, and routes with Svelte 5 (.svelte) equivalents per ADR-023react,@tanstack/react-router,@copilotkit/react-core,@ag-ui/coreand all related packagesuseAgUiChat.ts(971-line React hook) withchatStore.svelte.tsusing Svelte 5 runes — eliminates stale-closuremessagesRef/sessionsRefworkaroundseslint-plugin-svelte+svelte-eslint-parserreplacing the React ESLint pluginsChanges
Deleted (React):
App.tsx,main.tsx,router.tsand allhooks/,routes/*.tsx,components/chat/*.tsxAdded (Svelte 5):
App.svelte,main.ts, hash-based routerstore/chatStore.svelte.ts,store/backendStore.svelte.tsroutes/ChatLayout.svelte,ChatPage.svelte,SettingsPage.sveltecomponents/chat/*.svelteset including new components:AttachmentGroup,ReasoningGroup,ToolCallCard,ToolGroup,TurnFootercomponents/settings/BackendCard.svelte,HistorySourceCard.sveltestream-events.tsreplacing@ag-ui/corestring constants (ADR-023 §4)closes #79