import { createSignal, Show, For } from "solid-js"; import { ChatContainer, ChatContainerContent, ChatContainerScrollAnchor, Message, MessageAvatar, MessageContent, MessageActions, PromptInput, PromptInputTextarea, PromptInputActions, ConversationList, ModelSwitcher, PromptSuggestion, ScrollButton, Button, Separator, Context, ContextTrigger, ContextContent, ContextContentHeader, ContextContentBody, ContextContentFooter, ContextInputUsage, ContextOutputUsage, Reasoning, ReasoningTrigger, ReasoningContent, Tool, ThinkingBar, ChatConfig, } from "../index"; import type { ProseSize } from "../index"; import type { ConversationSummary, ConversationGroup, ModelOption, } from "../types"; import { Attachments, Attachment, AttachmentPreview, AttachmentInfo, AttachmentRemove, } from "../components/attachments"; import type { AttachmentData } from "../components/attachments"; import { ResizablePanelGroup, ResizablePanel, ResizableHandle } from "../ui/resizable"; import { Copy, ThumbsUp, ThumbsDown, RefreshCw, ArrowUp, Paperclip, Globe, Mic, Pencil, Trash, Plus, MoreHorizontal, } from "lucide-solid"; const scope = { type: "document" as const }; const groups: ConversationGroup[] = [ { id: "today", name: "Today", sortOrder: 0, createdAt: "2026-04-10" }, { id: "yesterday", name: "Yesterday", sortOrder: 1, createdAt: "2026-04-09" }, { id: "week", name: "Previous 7 Days", sortOrder: 2, createdAt: "2026-04-05", }, ]; const conversations: ConversationSummary[] = [ { id: "1", title: "SolidJS reactivity vs React hooks", groupId: "today", scope, messageCount: 8, lastMessageAt: "2026-04-10T15:30:00Z", updatedAt: "2026-04-10T15:30:00Z", }, { id: "2", title: "Tailwind v4 migration guide", groupId: "today", scope, messageCount: 14, lastMessageAt: "2026-04-10T11:20:00Z", updatedAt: "2026-04-10T11:20:00Z", }, { id: "3", title: "Chrome extension content scripts", groupId: "today", scope, messageCount: 6, lastMessageAt: "2026-04-10T09:00:00Z", updatedAt: "2026-04-10T09:00:00Z", }, { id: "4", title: "Vite HMR not working with web workers", groupId: "yesterday", scope, messageCount: 11, lastMessageAt: "2026-04-09T17:45:00Z", updatedAt: "2026-04-09T17:45:00Z", }, { id: "5", title: "IndexedDB vs OPFS performance", groupId: "yesterday", scope, messageCount: 9, lastMessageAt: "2026-04-09T14:00:00Z", updatedAt: "2026-04-09T14:00:00Z", }, { id: "6", title: "WebSocket reconnection strategies", groupId: "week", scope, messageCount: 7, lastMessageAt: "2026-04-07T10:30:00Z", updatedAt: "2026-04-07T10:30:00Z", }, { id: "7", title: "TypeScript discriminated unions", groupId: "week", scope, messageCount: 16, lastMessageAt: "2026-04-06T16:20:00Z", updatedAt: "2026-04-06T16:20:00Z", }, { id: "8", title: "CSS container queries", groupId: "week", scope, messageCount: 5, lastMessageAt: "2026-04-05T13:00:00Z", updatedAt: "2026-04-05T13:00:00Z", }, ]; const models: ModelOption[] = [ { id: "claude-4", name: "Claude 4 Opus", provider: "Anthropic" }, { id: "claude-4-sonnet", name: "Claude 4 Sonnet", provider: "Anthropic" }, { id: "gpt-4o", name: "GPT-4o", provider: "OpenAI" }, ]; const assistantResponse1 = `**SolidJS** takes a fundamentally different approach to reactivity compared to React hooks. ### Signals vs useState In SolidJS, signals are **fine-grained reactive primitives** that track their own subscribers. When a signal updates, only the specific DOM nodes that read that signal are updated — no virtual DOM diffing required. \`\`\`typescript // SolidJS — runs once, DOM updates surgically const [count, setCount] = createSignal(0); return

{count()}

; // only this text node re-renders // React — entire component re-renders const [count, setCount] = useState(0); return

{count}

; // whole function re-executes \`\`\` ### Key Differences 1. **No re-renders** — SolidJS components run once; only reactive expressions update 2. **No dependency arrays** — \`createEffect\` auto-tracks dependencies 3. **No stale closures** — signals are getter functions, always current 4. **Derived values** are just functions, no \`useMemo\` needed ### When to choose SolidJS - Performance-critical UIs with frequent updates - Projects where you want predictable reactivity - When you're tired of \`useCallback\` and dependency arrays`; const assistantResponse2 = `\`createEffect\` in SolidJS is synchronous by default and automatically tracks all reactive dependencies read inside it — no dependency array needed. \`\`\`typescript // SolidJS — auto-tracks count and name createEffect(() => { console.log(count(), name()); }); // React — must manually declare deps useEffect(() => { console.log(count, name); }, [count, name]); // easy to get wrong \`\`\` The biggest win: **no stale closure bugs**. Since \`count()\` is a function call, you always get the latest value. In React, closures capture the value at render time, which leads to subtle bugs with intervals, timeouts, and event handlers.`; /** The full chat application scene, shared by the Full Chat App story and the * theme editor's live preview. `class` controls the root sizing (defaults to * full-viewport; the editor passes `h-full` to fit its canvas). */ export function ChatScene(props: { class?: string }) { const [activeId, setActiveId] = createSignal("1"); const [modelId, setModelId] = createSignal("claude-4"); const [inputValue, setInputValue] = createSignal(""); const [proseSize, setProseSize] = createSignal("base"); const [attachedFiles, setAttachedFiles] = createSignal([ { id: 'att-1', type: 'file', filename: 'benchmark-results.pdf', mediaType: 'application/pdf', }, { id: 'att-2', type: 'file', filename: 'solid-vs-react.png', mediaType: 'image/png', url: 'https://images.unsplash.com/photo-1555949963-aa79dcee981c?w=400&h=400&fit=crop', }, { id: 'att-3', type: 'source-document', filename: 'SolidJS Docs', title: 'SolidJS Reactivity', url: 'https://solidjs.com/docs', }, ]); return (
{/* Sidebar */} {}} /> {/* Main Chat Area */}
{/* Header */}
SolidJS reactivity vs React hooks
{/* Chat Messages — scrollable */}
{/* User message 1 */}
Can you explain how SolidJS reactivity differs from React hooks? I keep hearing that SolidJS is faster but I don't understand why.
{/* Assistant message 1 */}
{assistantResponse1}
{/* User message 2 */}
What about effects? How does createEffect compare to useEffect?
{/* Assistant message 2 — last message, actions always visible */}
{assistantResponse2}
{/* User message 3 */}
Can you benchmark SolidJS vs React for a list of 10,000 items?
{/* Assistant message 3 — with reasoning + tool call */}
{/* Reasoning block */} Thought for 4 seconds {`I need to create a fair benchmark comparing SolidJS and React rendering performance. Let me think about the approach: - Both frameworks should render the same list of 10,000 items - I should measure initial render time and update performance - Need to use \`performance.now()\` for accurate timing - SolidJS should be significantly faster due to fine-grained reactivity`} {/* Tool call */} {`Here are the benchmark results for rendering 10,000 list items: | Metric | SolidJS | React | Difference | |--------|---------|-------|-----------| | Initial render | 12.4ms | 89.2ms | **7.2x faster** | | Single item update | 0.8ms | 34.1ms | **42.6x faster** | SolidJS's fine-grained reactivity really shines here — updating a single item in React triggers a full virtual DOM diff of all 10,000 items, while SolidJS surgically updates only the changed DOM node.`}
{/* Scroll button */}
{/* Input area — pinned to bottom */}
{/* Suggestions */}
setInputValue("How does SolidJS handle context?") } > How does SolidJS handle context? setInputValue("Show me a SolidJS store example") } > Show me a store example setInputValue("SolidJS vs Svelte comparison")} > SolidJS vs Svelte comparison
{/* Input */} setInputValue("")} >
{/* Attached files — inside the input container */} 0}>
{(file) => ( setAttachedFiles((prev) => prev.filter((f) => f.id !== file.id) ) } > )}
); }