Multi-Frontend Strategy
Kairos supports multiple frontends — CLI and Web App (React) — all powered by a single API backend.
Why a Unified API?
All clients go through one HTTP API — no exceptions:
graph TD
CLI["kairos-cli\n(clap)"]
Web["Web App\n(React)"]
Client["kairos-client\n(shared HTTP client)"]
API["kairos-api\n(axum server)"]
CLI --> Client
Web -->|HTTP/WS| API
Client -->|HTTP/WS| API
API --> Core["kairos-core"]
API --> Platform["kairos-platform"]
API --> LLM["kairos-llm"]
API --> DB["kairos-db"]
Benefits
| Benefit | Explanation |
|---|---|
| Single source of truth | Business logic lives in one place — the API layer |
| Behavioral consistency | All frontends produce identical results |
| Easier maintenance | Fix a bug once, all clients benefit |
| Auth in one place | API handles authentication; clients just pass tokens |
| Testable | API endpoints can be tested independently of any frontend |
Trade-offs
| Concern | Mitigation |
|---|---|
| CLI needs a running server | CLI can auto-spawn a local server if not running |
| Network overhead | Localhost HTTP adds < 1ms; LLM/scraping calls are seconds |
Prior Art
This is a well-established pattern:
- Docker CLI → Docker daemon REST API
- GitHub CLI (
gh) → GitHub REST/GraphQL API - Kubernetes
kubectl→ kube-apiserver - Terraform CLI → Terraform Cloud API
Shared Client Library
The CLI uses kairos-client — a Rust HTTP client library wrapping all API calls:
#![allow(unused)]
fn main() {
// kairos-client provides typed API access
let client = KairosClient::new("http://localhost:3001");
let jobs = client.jobs().search(criteria).await?;
let analysis = client.jobs().analyze(job_id).await?;
}
The Web App (React) calls the same API endpoints directly via fetch / WebSocket.
Frontend Summary
| Frontend | Technology | Connection | Timeline |
|---|---|---|---|
| CLI | clap + kairos-client | HTTP to API | Short term |
| Web App | React | HTTP/WS to API | Long term |