Skip to main content

Frontend Local Setup

The UniPulse web app is a React 19 SPA built with Vite 7. It communicates with the Express API and uses Zustand for client state and TanStack Query for server state.


Prerequisites

RequirementVersionPurpose
Node.js>= 20Runtime
npm>= 9Package manager
Backend APIRunning on port 3000See Backend Setup

Quick Start

# From the Pulse root directory
npm install

# Build the shared package first (required for type imports)
npm run build --filter=shared

# Start the web app
npm run dev --filter=web

The frontend starts on http://localhost:5173 and proxies API requests to http://localhost:3000.


Environment Configuration

cp apps/web/.env.example apps/web/.env
VariableDefaultDescription
VITE_API_URLhttp://localhost:3000Backend API base URL
Vite Environment Variables

Only variables prefixed with VITE_ are exposed to the client bundle. Never put secrets in VITE_* variables.


Tech Stack

TechnologyVersionPurpose
React19UI framework
Vite7Build tool with HMR
TypeScript5.9Type safety
Tailwind CSSv4Utility-first styling
shadcn/ui + Radix UILatestComponent library (accessible primitives)
Zustand5Client state management
TanStack Query5Server state (data fetching, caching, sync)
React Router7Client-side routing
RechartsLatestData visualization / charts
@xyflow/reactLatestWorkflow visual builder (React Flow)
react-i18nextLatestInternationalization (EN + AR)
Lucide ReactLatestIcon library
React Hook FormLatestForm state management
zodLatestValidation (via @unipulse/shared)
Alexandria-Font family (Latin + Arabic support)

Development Commands

# Start dev server with HMR
npm run dev --filter=web

# Type check
npm run typecheck --filter=web

# Build for production
npm run build --filter=web

# Preview production build
npm run preview --filter=web

# Add a new shadcn/ui component
cd apps/web && npx shadcn@latest add button

Project Structure

apps/web/src/
├── pages/ # 58+ page components (26 directories)
│ ├── dashboard/
│ ├── composer/
│ ├── analytics/
│ ├── ...
│ └── admin/
├── components/ # Shared UI components
│ ├── ui/ # shadcn/ui components
│ ├── layout/ # AppLayout, AuthLayout, SettingsLayout
│ ├── data-table/ # DataTable with sort/filter/pagination
│ └── charts/ # Recharts wrappers
├── stores/ # Zustand stores
│ ├── auth.store.ts
│ ├── workspace.store.ts
│ ├── ui.store.ts
│ └── composer.store.ts
├── hooks/ # Custom React hooks
├── lib/ # API client, utilities, cn() helper
├── i18n/ # Internationalization
│ ├── en/ # English JSON translation files
│ └── ar/ # Arabic JSON translation files
├── App.tsx # Root component with providers
└── main.tsx # Entry point

API Client

The API client is configured in apps/web/src/lib/api.ts. It automatically:

  • Attaches the JWT access token to every request
  • Refreshes expired tokens via /api/v1/auth/refresh
  • Handles workspace context headers
  • Types responses using @unipulse/shared types

Common Issues

IssueSolution
@unipulse/shared types not foundBuild shared: npm run build --filter=shared
API requests failing with CORSEnsure backend is running on port 3000
Blank page after loginClear localStorage and retry (token format may have changed)
Tailwind classes not applyingRestart dev server (Vite HMR sometimes misses Tailwind config changes)
Arabic text not rendering correctlyEnsure Alexandria font is loaded and dir="rtl" is set

Cross-Reference