A real-time cryptocurrency analytics dashboard built with React 19, TypeScript, and Vite.
- Real-time Market Data: Live prices via Binance WebSocket + CoinGecko API
- Watchlist & Portfolio: User-specific watchlists and portfolio tracking with P&L calculations
- Coin Details: Price charts, news feed, and market statistics
- Authentication: Clerk-powered auth with session timeout protection
- Performance: Aggressive caching (localStorage + TanStack Query) reduces API calls by 60-80%
- Frontend: React 19, TypeScript, Vite
- State: Zustand
- Data: TanStack Query, Binance WebSocket, CoinGecko API
- Auth: Clerk
- Styling: Tailwind CSS, Framer Motion
- Charts: Recharts
- Node.js 18+
- pnpm
- Clerk account
# Install dependencies
pnpm install
# Configure environment
cp .env.example .env
# Edit .env with your keys:
# VITE_CLERK_PUBLISHABLE_KEY=pk_test_...
# VITE_COINGECKO_API_KEY=CG-... (optional)
# Run dev server
pnpm devApp runs at http://localhost:5173
pnpm dev # Development server
pnpm build # Production build
pnpm test # Run tests
pnpm lint # Lint codegraph TD
Request[API Request]
CheckPageCache{Check Page Cache<br/>localStorage}
CheckCoinCache{Check Coin Cache<br/>localStorage}
Request --> CheckPageCache
CheckPageCache -->|Hit| ReturnPage[Return Cached Page<br/>TTL: 5 min]
CheckPageCache -->|Miss| CheckCoinCache
CheckCoinCache -->|Hit| ReturnCoins[Return Cached Coins<br/>TTL: 5 min]
CheckCoinCache -->|Miss| FetchAPI[Fetch from CoinGecko API]
FetchAPI --> StorePage[Store Page Cache<br/>Max 500 items]
FetchAPI --> StoreCoins[Store Coin Cache<br/>Max 500 items]
StorePage --> TanStackQuery[TanStack Query Cache<br/>staleTime: 5 min<br/>gcTime: 30 min]
StoreCoins --> TanStackQuery
ReturnPage --> TanStackQuery
ReturnCoins --> TanStackQuery
TanStackQuery --> CheckExpiry{Check TTL}
CheckExpiry -->|Expired| EvictLRU[LRU Eviction<br/>Clean Expired Items]
CheckExpiry -->|Valid| ReturnData[Return to UI]
EvictLRU --> ReturnData
style Request fill:#4A90E2
style FetchAPI fill:#FF6B6B
style TanStackQuery fill:#50C878
style ReturnData fill:#7B68EE
sequenceDiagram
participant App as React App
participant Hook as useBinanceWebSocket
participant WS as Binance WebSocket
participant Store as Zustand Store
participant UI as UI Components
App->>Hook: Component Mount
Hook->>WS: Connect to wss://stream.binance.com:9443/ws/!miniTicker@arr
Note over WS: Continuous Stream<br/>All Market Mini Tickers
loop Every Message
WS->>Hook: Receive Ticker Array
Hook->>Hook: Filter USDT Pairs Only
Hook->>Hook: Normalize Symbol<br/>BTCUSDT → btc
Hook->>Hook: Parse Price Data<br/>close, open, high, low, volume
Hook->>Hook: Calculate 24h Change %
alt Valid Data
Hook->>Store: updateLivePrices(updates)
Store->>UI: Trigger Re-render
UI->>UI: Display Live Prices
else Invalid Data
Hook->>Hook: Log Error & Skip
end
end
App->>Hook: Component Unmount
Hook->>WS: Close Connection
src/App.tsx- Main routes and layoutsrc/store/useStore.ts- Global state (Zustand)src/hooks/- Custom hooks (WebSocket, session timeout, data sync)src/api/cryptoApi.ts- API integrationssrc/utils/coinCache.ts- Caching utilitiessrc/components/- UI components