Skip to content

Frontend Overview

The VibeXP frontend is a single-page application (SPA) that lives in the frontend/ directory of the vibexp/vibexp monorepo. It is built and released independently from the backend.

  • Vite — build tool and dev server.
  • React 19 with TypeScript — UI layer.
  • React Router — client-side routing.
  • nginx — serves the static build in production and reverse-proxies the API.

Node.js >= 20 is required (enforced by the engines field in package.json).

The frontend consumes two npm packages that are not in this repo. Both are maintained in separate repositories and resolved from the public npm registry:

  • @vibexp/api-client — a typed API client generated from the backend’s openapi.yaml. This is how the SPA calls the backend; you do not hand-write fetch calls against the REST API.
  • @vibexp/design-system — the shared UI component library (design tokens, primitives, themed components).

Because both come from npm, the frontend build is fully standalone — no monorepo workspace context and no auth token are needed to build it.

frontend/src/
├── pages/ Route-level views (one per screen)
├── components/ Reusable presentational components
├── features/ Feature modules (domain-grouped UI + logic)
├── hooks/ Custom React hooks
├── contexts/ React context providers (auth, theme, …)
├── services/ API calls and side-effecting integrations
├── lib/ Third-party wiring and shared setup
└── utils/ Pure helpers and small utilities

The frontend is deployment-agnostic. It is built with a relative API base URL — VITE_API_BASE_URL=/api/v1 — so all requests are same-origin. In production, nginx reverse-proxies /api/ to the backend, whose location is set at deploy time via the BACKEND_ORIGIN runtime variable (default http://backend:8080).

This means the backend origin is never baked into the build. The same published image works against any backend. See Frontend Configuration for the build-time vs runtime split, and Building & Serving for the nginx proxy details.

Authentication is handled by the backend via WorkOS AuthKit; the frontend never holds API keys or OAuth secrets.

  1. The user starts sign-in from the SPA, which redirects to the backend auth endpoint.
  2. The backend completes the WorkOS flow and returns to the SPA’s /auth/callback route.
  3. The session is carried in an httpOnly session cookie set by the backend — it is not readable by JavaScript, and is sent automatically on same-origin /api/v1 requests through the nginx proxy.

Local development uses the root Makefile, not Docker:

Terminal window
make frontend-run-dev

This installs dependencies if needed, copies frontend/.env from .env.example if missing, and starts the Vite dev server at http://localhost:5173.

Run these before committing (CI runs the same targets):

Terminal window
make frontend-install # install dependencies
make frontend-lint # eslint
make frontend-type-check # tsc
make frontend-test # tests
make frontend-build # production build