sandgardenhq/sgai/react-sse-patterns
Claude Code and agent skill by sandgardenhq/sgai
- community
Checking that the SKILL.md file is still in the repository.
SSE with useSyncExternalStore, reconnection with exponential backoff, snapshot rehydration, typed event parsing, connection status UI. Use when implementing SSE data stores, real-time update hooks, or connection resilience in the React SPA. Triggers on SSE, EventSource, useSyncExternalStore, real-time updates, reconnection, or live data tasks.
Install
npx vskill@latest install sandgardenhq/sgai/react-sse-patternsSKILL.md
React SSE Patterns
Overview
Guide for implementing Server-Sent Events (SSE) in the SGAI React SPA using React's useSyncExternalStore pattern. Covers the external store module, auto-reconnect with exponential backoff, snapshot rehydration on reconnect, typed event parsing, connection status UI, and domain hooks that combine initial fetch with live SSE updates.
STPA References: R-1 (auto-reconnect), R-2 (connection status banner), R-3 (unbounded reconnection), R-19 (snapshot rehydration).
When to Use
- Use when building or modifying
lib/sse-store.ts - Use when creating domain hooks that subscribe to SSE events (e.g.,
useWorkspaces,useSession) - Use when implementing connection status indicators
- Use when debugging SSE reconnection or stale data issues
- Don't use for non-SSE data fetching patterns (use
react-best-practicesinstead)
Architecture
Key constraint: The SSE store is an external store, NOT a React Context. This follows React's official recommendation for external data sources. Components subscribe via useSyncExternalStore(store.subscribe, store.getSnapshot).
Process
Step 1: SSE Store Module (lib/sse-store.ts)
The SSE store is a standalone TypeScript module that manages the EventSource connection at module level.
Step 2: Exponential Backoff (R-1, R-3)
Reconnection uses exponential backoff: 1s → 2s → 4s → 8s → 16s → 30s (max).
Rules:
- Base delay: 1 second
- Multiplier: 2x per attempt
- Maximum delay: 30 seconds
- Never give up — reconnection attempts are unbounded (R-3)
- Reset attempt counter to 0 on successful connection
Step 3: Snapshot Rehydration (R-19)
On initial connect or reconnect, the SSE endpoint sends a full state snapshot as the first event. This prevents stale data after reconnection.
Server-side contract: GET /api/v1/events/stream sends a snapshot event as the first message containing the complete current state. After that, incremental events follow.
Client-side handling:
Step 4: Connection Status UI (R-2)
Show a "Reconnecting..." banner when disconnected for more than 2 seconds.
Step 5: Typed Event Parsing
All SSE events have typed names. Parse and validate on receive:
| Event Name | Payload Type | Description | |
|---|---|---|---|
workspace:update | WorkspaceData | Workspace list/detail changed | |
session:update | SessionData | Session status, current agent, workflow state | |
messages:new | MessageData | New inter-agent message | |
todos:update | TodoData | Todo list changed | |
log:append | LogData | New output log lines | |
changes:update | ChangesData | JJ diff changed | |
events:new | EventData | New progress event | |
compose:update | ComposeData | GOAL.md composer state |
Define TypeScript interfaces for each payload in types/sse.ts.
Step 6: Domain Hooks (Initial Fetch + SSE)
Domain hooks combine an initial API fetch with SSE live updates:
Pattern: Every domain hook follows this structure:
use(fetchPromise)for initial data (wrapped in Suspense)useSyncExternalStorefor live SSE updates- Return SSE data when available, fall back to initial fetch
Rules
- SSE store is NOT React Context — It's a module-level external store. Components subscribe via
useSyncExternalStore. This is React's recommended pattern for external data sources.
- Never give up reconnecting — Reconnection is unbounded. The store retries forever with exponential backoff capped at 30s. Users should always see fresh data eventually.
- Snapshot first, incremental after — On every connect/reconnect, the server sends full state. The client replaces its entire cache from the snapshot, then applies incremental events.
- Show connection status after 2s — Don't flash banners on brief disconnects. Only show "Reconnecting..." if disconnected for >2 seconds.
- Domain hooks combine fetch + SSE — Initial page data comes from
use()+ Suspense. SSE keeps it fresh. Never use only one or the other for data that changes.
- SSE events published after commit — The Go backend emits SSE events AFTER transaction commit (R-20), never during mutation. This prevents the React UI from seeing uncommitted state.
Examples
Good: External store with useSyncExternalStore
Bad: SSE in React Context
Good: Domain hook with fetch + SSE
Bad: Only SSE, no initial fetch
Checklist
Before completing SSE work, verify:
- [ ] SSE store uses
useSyncExternalStore, not React Context - [ ] Exponential backoff: 1s → 2s → 4s → max 30s
- [ ] Reconnection is unbounded (never gives up)
- [ ] Snapshot rehydration on connect/reconnect
- [ ] Connection status banner appears after >2s disconnect
- [ ] All 8 event types have TypeScript interfaces
- [ ] Domain hooks combine
use()+useSyncExternalStore - [ ] SSE events are emitted server-side after transaction commit
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewNot runA model review is scheduled for the next rescan.
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingcmd/sgai/skel/.sgai/skills/coding-practices/react-sse-patterns/SKILL.md
Popularity
- Repository stars
- 113
- Repository forks
- 6
- 7-day trend score
- 24
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 27 Mar 2026, 7 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/sandgardenhq/sgai/react-sse-patterns)