How the llmfit Axum Server Routes Between the React Dashboard and `/api/v1/` JSON Endpoints
The llmfit TUI embeds a React SPA and mounts it at the root path while nesting JSON API routes under /api/v1/ using Axum’s nest() method, with a fallback handler that rewrites unknown paths to index.html to support client-side routing.
The llmfit project by AlexsJones demonstrates a unified web architecture where a single Rust binary serves both a React-based management dashboard and a programmatic JSON API. According to the source code in llmfit-tui/src/serve_api.rs, the application uses Axum’s composable routing to distinguish between static asset requests and API calls, eliminating the need for a separate web server or reverse proxy.
Mounting the /api/v1/ JSON API Routes
The programmatic interface is isolated under the /api/v1/ prefix using Axum’s nest() method. In llmfit-tui/src/serve_api.rs, the code constructs a sub-router dedicated to API endpoints and mounts it at the specified path.
The API router defines concrete handlers for hardware inspection, model management, and execution planning:
// llmfit-tui/src/serve_api.rs
let api_router = Router::new()
.route("/hardware", get(handlers::hardware))
.route("/models", get(handlers::models))
.route("/plan", post(handlers::plan));
let app = Router::new()
.nest("/api/v1", api_router); // Mounts API routes under /api/v1/*
Each handler in this sub-router invokes functions from the llmfit-core library and returns structured JSON via axum::Json<T>. This separation ensures that all programmatic endpoints share a common prefix and can apply uniform middleware, such as authentication or logging, at the nest boundary.
Serving the React Dashboard with Embedded Static Assets
The React frontend is embedded directly into the binary at compile time using the include_dir! macro. In llmfit-tui/src/main.rs, the static assets from llmfit-web/dist are compiled into the executable, allowing the Axum server to serve the dashboard without filesystem dependencies.
// llmfit-tui/src/main.rs
use include_dir::{Dir, include_dir};
static STATIC_ASSETS: Dir = include_dir!("$CARGO_MANIFEST_DIR/llmfit-web/dist");
To serve these assets, the router uses tower-http’s ServeDir service. A fallback route captures any unmatched paths and rewrites them to index.html, enabling the React router to handle client-side navigation:
// llmfit-tui/src/serve_api.rs
use tower_http::services::ServeDir;
let app = Router::new()
.nest("/api/v1", api_router)
.fallback_service(
get_service(ServeDir::new(STATIC_ASSETS.path()))
.handle_error(|e| async move {
(StatusCode::INTERNAL_SERVER_ERROR, format!("Error: {}", e))
})
);
This configuration ensures that requests to /dashboard or /settings—which do not match any API route—return the React index.html file rather than a 404 error.
Combining Routes in the Application Router
The final router composition occurs in serve_api.rs, where the API sub-router and the static file service are merged into a single axum::Router instance. The nest() method prefixes all API routes, while the fallback_service() handles all non-API traffic.
// Simplified structure from llmfit-tui/src/serve_api.rs
let api_router = Router::new()
.route("/hardware", get(hardware::handler))
.route("/models", get(models::handler))
.route("/plan", post(plan::handler));
let app = Router::new()
.nest("/api/v1", api_router) // JSON endpoints
.fallback_service(
get_service(ServeDir::new(STATIC_ASSETS.path()))
.handle_error(|e| async move {
(StatusCode::INTERNAL_SERVER_ERROR, format!("Server error: {}", e))
})
);
When the server starts, axum::Server::bind() listens on the configured address and dispatches incoming requests according to this hierarchy: exact matches for /api/v1/* go to the API handlers, while all other requests trigger the static file service or the fallback to index.html.
Summary
- Unified Binary: The
llmfit-tuicrate combines a React SPA and JSON API in a single Axum server, embedding static assets withinclude_dir!to eliminate runtime file dependencies. - Path Prefixing: All programmatic endpoints are mounted under
/api/v1/usingRouter::nest(), creating a clean separation between API and UI routes. - Client-Side Routing Support: A fallback service rewrites unknown paths to
index.html, allowing the React dashboard to manage its own navigation while the server handles only data endpoints. - Source Locations: Routing logic resides in
llmfit-tui/src/serve_api.rs, while asset embedding occurs inllmfit-tui/src/main.rs.
Frequently Asked Questions
How does the llmfit server distinguish between API requests and dashboard requests?
The server uses Axum’s nest() method to isolate all JSON endpoints under the /api/v1/ prefix. Any request path starting with /api/v1/ routes to the dedicated API sub-router defined in llmfit-tui/src/serve_api.rs. All other requests fall through to the ServeDir static file handler or the index.html fallback, ensuring the React dashboard receives control of the browser routing.
Why does the server embed the React build instead of using an external directory?
The project uses the include_dir! macro to embed llmfit-web/dist directly into the compiled binary at build time. This approach creates a self-contained executable that does not require external static asset directories, simplifying deployment and ensuring the dashboard version remains synchronized with the server binary.
How does the Axum router handle React client-side routing?
The router includes a fallback service configured with ServeDir that rewrites any unmatched paths to index.html. When a user navigates to a client-side route like /dashboard/models, the server returns the React application bundle, and the browser-side React Router interprets the path and renders the appropriate component without additional server configuration.
What endpoints are available under the /api/v1/ prefix?
According to the router definition in serve_api.rs, the API exposes endpoints such as GET /api/v1/hardware for system specifications, GET /api/v1/models for available LLM configurations, and POST /api/v1/plan for generating execution plans. These handlers reside in the llmfit-core library and return JSON responses consumed by the React dashboard or external tools.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →