Frontend Development
Next.js patterns, feature modules, and code generation
The Vezta frontend is a Next.js 16 App Router application built with React 19, Tailwind CSS v4, and TanStack Query v5. It runs on port 3000 and connects to the backend API at localhost:3001.
Project Structure
app/
├── (landing)/ # Public marketing pages (1440px max-width)
├── (dashboard)/ # Main app with AppLayout (Navbar + BottomStatusBar)
└── (auth)/ # Login, onboarding, access-key (no shell chrome)
features/
├── markets/ # Market browsing, search, terminal
├── portfolio/ # Positions, orders, analytics
├── trading/ # Order form, execution
├── social/ # Leaderboard, copy trade, wallet tracker
├── monitor/ # News feed, signal detection
├── rewards/ # Points, missions, challenges
└── ... # auth, events, overlays, settings
components/
├── ui/ # shadcn/ui primitives (new-york style)
├── layout/ # AppLayout, Navbar, BottomStatusBar
└── states/ # Skeletons, empty states, error states
lib/
├── api/gen/ # Auto-generated (never hand-edit)
├── api/client.ts # Fetch wrapper with auth + retry
├── api/auth.ts # In-memory access token management
├── ws/ # Socket.IO + Jotai atoms
├── trading/ # PnL helpers, price impact
├── types/ # TypeScript interfaces
├── utils.ts # cn(), formatUsd, timeAgo, etc.
└── constants.ts # Categories, filters, nav items
hooks/ # Custom hooks (order form, media query, etc.)
providers/ # ThemeProvider, QueryProvider, AuthProvider, etc.Key Patterns
Feature Modules
Business logic lives in features/{domain}/components/, not in flat component directories. Each feature domain contains its own components and hooks. Pages in app/ compose these feature components.
State Management
- TanStack Query v5 -- server state, caching, and data fetching via auto-generated hooks
- Zustand -- UI state (e.g., terminal sidebar panel order and visibility)
- Jotai -- WebSocket atoms for real-time data (prices, orderbook, trades)
- URL state -- route params for market slugs (
/market/[slug])
TanStack Query is configured with refetchOnWindowFocus: false, which differs from the default. This is intentional for a trading terminal where stale data is refreshed via WebSocket, not tab focus.
API Integration
All API hooks are auto-generated by Kubb from the backend's OpenAPI spec. The generated code lives in lib/api/gen/ and must never be hand-edited. See API Client Generation for the full pipeline.
The custom fetch wrapper at lib/api/client.ts provides Bearer token injection, automatic 401 refresh-and-retry with a promise lock (preventing multiple simultaneous refreshes), and credentials: 'include' for cookies. All generated hooks use this wrapper via a Kubb fetch alias in next.config.ts.
Auth System
Wallet-based auth with a two-cookie system:
- Backend sets an httpOnly
refresh_tokencookie (7 days) - Frontend sets a non-httpOnly
logged_in=1cookie for middleware route protection - Access token is stored in-memory (not localStorage) to prevent XSS
- Middleware only reads
logged_in-- never the actual refresh token
Design System
- Dark mode only (forced via ThemeProvider)
- Accent color: lime-green
#D4FF2B(bg-primary/text-primary) - Fonts: Space Grotesk for headings/UI, JetBrains Mono for prices/data
- Green (
#22C55E) = YES/Buy/Profit; Red (#EF4444) = NO/Sell/Loss - Tailwind v4 with CSS-first config via
@themeblock inapp/globals.css - Icons from
lucide-react
There is no tailwind.config.js. Tailwind v4 uses CSS variables defined in the @theme block in app/globals.css. Do not create a JS config file.
Dev Commands
pnpm dev # Dev server on port 3000 (uses --webpack for WASM)
pnpm build # Production build (Turbopack, no --webpack)
pnpm test # Vitest
pnpm test -- --testPathPattern=navbar # Run a single test
pnpm lint # ESLint
pnpm generate # Kubb: regenerate API client from OpenAPI specEnvironment Variables
| Variable | Default | Purpose |
|---|---|---|
NEXT_PUBLIC_API_URL | http://localhost:3001/api/v1 | Backend API base |
NEXT_PUBLIC_WS_URL | ws://localhost:3001 | WebSocket endpoint |
OPENAPI_PATH | http://localhost:3001/docs-json | Kubb OpenAPI source |
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID | -- | Reown WalletConnect ID |
NEXT_PUBLIC_SOLANA_RPC_URL | mainnet-beta | Solana RPC endpoint |