Architecture

One core, truly independent apps

Kubuno is not a monolith. A small Rust core orchestrates a constellation of self-contained modules — each with its own process, its own repository and its own packages — which talk to one another over HTTP and through shared events. Here is how it all fits together.

CLIENTS Web browser Desktop app Mobile API / CLI clients HTTPS Frontend host · React 19 Unified shell — loads each module's UI at runtime via ESM import maps authenticated request (JWT) Core · Rust + Axum Reverse proxy Authentication Event bus Storage reverse proxy · internal secret INDEPENDENT MODULES · separate processes on 127.0.0.1 Office :3105 Drive :3101 Mail :3111 p2pnas :3123 Assistant :3107 +18 each registers with the core at startup · native package or hot install SQL · NOTIFY/LISTEN · job queue PostgreSQL 16 — one engine, three roles Database Event bus · LISTEN/NOTIFY Job queue · SKIP LOCKED

The layers

Six layers, clear responsibilities

The core (Rust + Axum)

A single gateway: reverse proxy (HTTP and WebSocket), authentication, event bus, job queue and storage access. It drives the module lifecycle but holds no business logic.

Independent modules

Each app is a separate process on 127.0.0.1, shipped as a native package (.deb, .rpm, macOS, Windows) or installed on the fly from the marketplace — without restarting the core.

Frontend loaded at runtime

A single React 19 host loads each module's UI on the fly through ESM import maps. Every app shares a consistent shell, session and design.

PostgreSQL, three jobs in one

One engine plays three roles: database, event bus (LISTEN/NOTIFY) and job queue (SKIP LOCKED). No Redis, no external broker.

Isolated & secure

A dedicated PostgreSQL schema per app, a seccomp sandbox that makes execve fail (except for the few modules that legitimately shell out, such as video transcoding), and internal routes signed with a per-module derived secret.

Ready for AI agents (MCP)

Any module can declare Model Context Protocol tools; the core aggregates them behind a single /mcp endpoint, authenticated by API token. An assistant then acts on your instance with your permissions. Off by default.

Extensible by design

Well-defined extension points (routes, events, menu entries) let the community add modules without touching the core.

Under the hood

The life of a request

From opening the browser to writing to the database, without ever leaving your server.

1

The shell loads

The browser loads the React host; import maps resolve each module to its ESM entry /modules/<id>/entry.js.

2

An authenticated call

The app sends its request to the core over HTTPS, along with a JWT (and a refresh token in an HttpOnly cookie).

3

The core acts as the gateway

It verifies the identity, then reverse-proxies to the target module on 127.0.0.1:31xx, with a signed internal header (X-Internal-Secret).

4

The module does its work

The module reads or writes in its own PostgreSQL schema, then publishes an event with NOTIFY.

5

Reactions & background work

Other modules react to the event (LISTEN); long-running work goes to the job queue (SKIP LOCKED).

Want to dig deeper?

The technical documentation covers the core, the module manifest, extension points and security.

Read the technical docs