Embedded Dashboard Pipeline
Relevant source files
The following files were used as context for generating this wiki page:
The Embedded Dashboard Pipeline is a sophisticated build and distribution mechanism that integrates a React-based management interface directly into the Honmoon Rust binary. This architecture ensures that the data plane gateway and its management UI are distributed as a single, self-contained executable, simplifying deployment and ensuring version parity between the enforcement engine and the operator's view.
The pipeline spans two primary ecosystems: a TypeScript/Vite frontend environment for the dashboard and a Rust environment for the management API. During the build process, the dashboard is compiled into static assets and then embedded into the honmoon-mgmt crate using the rust-embed crate. At runtime, these assets are served by an Axum web server integrated into the Honmoon gateway process.
Build-Time Orchestration
The integration begins at the build stage, where the Rust compiler interacts with the frontend build artifacts. To maintain a robust developer experience even when frontend dependencies are not yet installed or built, the pipeline includes a fallback mechanism.
Rust Build Script (build.rs)
The honmoon-mgmt crate utilizes a build.rs script to manage the dependency on the dashboard's distribution folder. If the apps/dashboard/dist directory (where Vite outputs compiled assets) does not exist, the script creates a placeholder index.html. This prevents the Rust compilation from failing due to missing files during initial setup or in environments where only the data plane is being developed.
Sources: crates/honmoon-mgmt/build.rs:1-36, wiki/deep-dive/control-plane.md:73-80
Frontend Compilation
The dashboard is a React 19 SPA built with Vite and Tailwind CSS. The build process transforms the source code in apps/dashboard/src into optimized static assets in apps/dashboard/dist.
| Phase | Tool | Output |
|---|---|---|
| Frontend Build | bun run build (Vite) | apps/dashboard/dist/ |
| Embedding | rust-embed macro | In-memory asset map in Rust binary |
| Backend Build | cargo build | honmoon binary |
Sources: apps/dashboard/AGENTS.md:12-16, wiki/deep-dive/control-plane.md:73-80
Architecture and Data Flow
The pipeline supports two distinct operational modes: one optimized for rapid frontend development and one for production distribution.
This diagram illustrates the transition from frontend source code to a served production binary, as well as the proxy-based development workflow.
Sources: apps/dashboard/vite.config.ts:13-20, wiki/deep-dive/control-plane.md:82-90
Development Proxying
During development, the dashboard runs on a Vite dev server (typically port 5173). To avoid Cross-Origin Resource Sharing (CORS) issues and simulate the production environment, vite.config.ts is configured to proxy all requests starting with /api to the management API running in a local honmoon gateway instance (typically port 8444).
// apps/dashboard/vite.config.ts
export default defineConfig({
// ... configuration
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8444',
changeOrigin: true,
},
},
},
})
Sources: apps/dashboard/vite.config.ts:13-20, wiki/deep-dive/control-plane.md:92-95
Asset Embedding and Serving
The honmoon-mgmt crate is responsible for the actual embedding and the logic for serving those assets to users.
The Assets Structure
The pipeline uses the rust-embed crate to define a struct that represents the dashboard assets. This macro-driven approach effectively bakes the contents of the dist folder into the binary as byte arrays.
// crates/honmoon-mgmt/src/lib.rs
#[derive(RustEmbed)]
#[folder = "../../apps/dashboard/dist/"]
struct Assets;
Sources: crates/honmoon-mgmt/src/lib.rs:30-32, wiki/deep-dive/control-plane.md:73-77
Axum Routing and SPA Fallback
The management server uses the Axum framework to route requests. It distinguishes between API calls and asset requests:
- API Routes: Prefixed with
/api, these are handled by Rust functions interacting with the data plane's audit logs and approval registries. - Asset Routes: Any path not matching an API route is checked against the embedded
Assets. - SPA Fallback: If a request does not match an API route or a specific static file (like
main.js), the server returnsindex.html. This allows the React Router on the frontend to handle deep-linked URLs (e.g.,/approvals) while still serving the initial application from the root.
To ensure technical accuracy and prevent masking errors, the fallback logic explicitly refuses to serve index.html for unmatched paths beginning with /api/, allowing them to return a standard 404 error instead.
Sources: crates/honmoon-mgmt/src/lib.rs:138-168, wiki/deep-dive/control-plane.md:65-71
Key Components Summary
| Component | Location | Role |
|---|---|---|
build.rs | crates/honmoon-mgmt/ | Ensures a placeholder exists for the embed macro during Rust-only builds. |
vite.config.ts | apps/dashboard/ | Configures the dev-time API proxy and build-time optimization. |
Assets Struct | crates/honmoon-mgmt/src/lib.rs | The rust-embed bridge that includes assets in the binary. |
serve_asset | crates/honmoon-mgmt/src/lib.rs | The Axum handler that retrieves bytes from the Assets struct and sets MIME types. |
Sources: crates/honmoon-mgmt/build.rs:1-36, apps/dashboard/vite.config.ts:1-21, crates/honmoon-mgmt/src/lib.rs:148-168
Conclusion
The Embedded Dashboard Pipeline represents a tight coupling between the Honmoon data plane and its management interface. By utilizing rust-embed and a custom Axum serving strategy with SPA fallback, the project achieves a "single binary" deployment model. This ensures that operators always have access to a compatible management dashboard directly from the gateway instance they are running.