Skip to content

Frontend Architecture

Tech Stack

  • React 18 with TypeScript
  • Vite for dev server and builds
  • MUI v6 (Material UI) with dark/light theme
  • Zustand for lightweight state management
  • Axios for HTTP with JWT interceptors
  • React Router v6 for client-side routing
  • @monaco-editor/react for YAML/JSON inspection
  • @xyflow/react for DAG workflow visualization
  • xterm.js for container terminal

Directory Structure

frontend/src/
├── api/                # Axios client + typed API functions
│   ├── client.ts       # Base axios instance with JWT interceptors + getErrorMessage()
│   ├── auth.ts         # Auth API calls
│   ├── containers.ts   # Container/image/volume/network/system API calls
│   ├── settings.ts     # Settings/API key API calls
│   └── workspaces.ts   # Workspace + artifact API calls
├── store/              # Zustand stores
│   ├── authStore.ts
│   ├── containerStore.ts
│   ├── dashboardStore.ts
│   ├── themeStore.ts
│   ├── toastStore.ts
│   └── workspaceStore.ts
├── components/         # Shared UI components
│   ├── Layout.tsx              # App shell with sidebar, header, footer
│   ├── SetupDialog.tsx         # First-run API key setup
│   ├── ToastContainer.tsx      # Toast notification display
│   ├── InspectDrawer.tsx       # Monaco-based JSON inspector
│   ├── DirectoryBrowser.tsx    # Workspace directory picker
│   ├── ContainerTerminal.tsx   # xterm.js container exec
│   ├── WebSocketTerminal.tsx   # Generic WebSocket terminal
│   ├── WorkspaceDag.tsx        # DAG visualization wrapper
│   └── graph/                  # DAG node/edge components
│       ├── ContainerDetailPanel.tsx
│       └── EdgeDetailPanel.tsx
├── pages/              # Route pages
│   ├── LoginPage.tsx
│   ├── DashboardPage.tsx
│   ├── WorkspacesPage.tsx
│   ├── WorkspaceDetailPage.tsx
│   ├── ContainersPage.tsx
│   ├── ContainerDetailPage.tsx
│   ├── ImagesPage.tsx
│   ├── VolumesPage.tsx
│   ├── NetworksPage.tsx
│   ├── ObservabilityPage.tsx
│   ├── DiskUsagePage.tsx
│   ├── SettingsPage.tsx
│   └── DocsPage.tsx
├── App.tsx             # Router + theme provider
├── main.tsx            # Entry point
└── theme.ts            # MUI theme config (dark + light)

Auth Flow

  1. User clicks GitHub OAuth button
  2. Callback returns code query param to /login?provider=github&code=...
  3. Frontend exchanges code via /api/auth/github → receives JWT pair
  4. Access token stored in localStorage, attached to all API calls via interceptor
  5. On 401, interceptor clears tokens and redirects to /login