Zum Inhalt springen
Origin
MITDokumentation
Rust · Tauri · Referenzarchitektur · Open Source

Domain-Code weiß nicht,
dass es Tauri gibt

Origin ist kein Framework, das Tauri ersetzt, und kein Monolith-Crate. Es ist ein Satz verbindlicher Architekturregeln, wiederverwendbarer Plattform-Crates und Build-Prozesse – plus eine Referenzanwendung, die alles davon vorführt.

Testbar ohne Tauri

Die Qualitätsprüfung der Architektur: cargo test --workspace läuft ohne Desktop-Session.

Maschinell geprüft

cargo xtask validate bricht ab, wenn ein Crate unter crates/ von tauri abhängt.

Einzeln nutzbar

Die origin-*-Crates liegen auf crates.io und bleiben auch außerhalb von Origin verwendbar.

Stand: September 2026 · v0.2.0
18
Plattform-Crates
10
Adapter
31
Architecture Decision Records
forbid
unsafe_code im Workspace
01 — Überblick

Eine neue Desktop-App sollte Auth, Storage und Sync nicht neu erfinden müssen.

Origin sammelt die Teile, die in jeder Desktop-Anwendung wieder anfallen – Authentifizierung, Speicherung, Synchronisation, Berechtigungen, Benachrichtigungen, Logging, Projektstruktur – und legt sie als eigenständige Rust-Crates ab. Tauri bleibt dabei der Host, nicht das Fundament.

Dokumentation →
  1. 01Regeln statt Konventionen — 15 verbindliche Architekturregeln, geprüft von cargo xtask validate
  2. 02Contract-Tests — jede austauschbare Implementierung besteht dieselbe Test-Suite, In-Memory-Double wie System-Keychain
  3. 03Typisierte Eventsbus.subscribe::<PlatformEvent>() statt bus.on("sync:done"); ein umbenanntes Feld ist ein Compile-Fehler
  4. 04Begründete Entscheidungen — 31 ADRs halten fest, warum eine Regel so lautet, und wie man begründet abweicht
02 — Aufbau

Verträge unten, Adapter darüber, Tauri ganz außen.

  1. crates/

    Plattform und Verträge

    18 Crates von origin-domain über origin-auth, origin-sync und origin-jobs bis origin-app. Keines davon darf tauri oder ein tauri-plugin-* kennen.

    origin-domainorigin-app
  2. adapters/

    Konkrete Implementierungen

    SQLite, System-Keychain, reqwest, Loopback-Redirect nach RFC 8252, MCP über stdio und HTTP, Workspace-Dateizugriff und -Watching – zehn Stück, austauschbar.

    SQLitekeyringreqwest
  3. host/origin-tauri

    Der Desktop-Host

    Plugin-Verdrahtung, Tray, IPC-Kommandos und die Event-Brücke. Eine von mehreren gleichberechtigten Driving-Adapters – MCP-Server, CLI und Headless-Betrieb stehen daneben.

    Tauri 2IPC
  4. frontend/

    Die einzige Stelle mit IPC

    @casoon/origin-client ist das einzige Paket, das Tauri-IPC kennt; @casoon/origin-ui liefert Svelte-5-Komponenten und Design-Tokens. Views rufen keine Tauri-API direkt auf.

    TypeScriptSvelte 5
  5. app.toml + xtask

    Manifest statt kopierter Config

    Das Manifest sagt, was das Produkt ist; cargo xtask generate leitet Capability-Dateien und TypeScript-Contracts daraus ab. Generierte Dateien sind Origin-eigen und werden nicht von Hand editiert.

    app.tomlgenerate --check
03 — Schichten

Abhängigkeiten zeigen nur nach unten.

ARCHITECTURE.mdSchichtenmodell
PRODUCT APP            examples/demo, later other independent products
  ↓ composition root
DRIVING ADAPTERS       Tauri host · MCP server · CLI · headless — all equal peers
APPLICATION MODULES    ApplicationModule implementations
  ↓
CONNECTORS             external service integrations
  ↓
ORIGIN PLATFORM        crates/origin-{events,secrets,settings,storage,http,auth,
                       accounts,connector,sync,jobs,mcp,ai,telemetry,app}
TOOLING                crates/origin-{manifest,xtask} — build time, not runtime
  ↓
PLATFORM CONTRACTS     crates/origin-platform, crates/origin-domain (ports)
  ↓
TAURI HOST             host/origin-tauri, adapters/origin-*-tauri
04 — Plattform

Was eine Anwendung von Origin geschenkt bekommt.

Ein Fehlermodell

Adapter übersetzen rusqlite-, reqwest- und tauri-Fehler an der Grenze in AppError. Das Frontend verzweigt über kind statt über Fehlertexte.

OAuth ohne Abkürzungen

PKCE immer, state wird vor dem Code geprüft, Loopback-Redirect statt eigenem URL-Schema, Single-Flight-Refresh. Eine Refresh-Antwort ohne refresh_token behält den alten.

Die Engine besitzt den Zeitplan

Ein Connector sagt, wie geholt wird; origin-sync bestimmt wann – mit Backoff, Jitter, Offline-Behandlung und Validatoren. Getestet wird mit einer Fake-Clock, nicht mit sleep.

Zugangsdaten im OS-Keychain

Niemals in der Anwendungsdatenbank, adressiert pro Konto. Ein Konto zu trennen löscht per Namespace-Konvention alles, was darunter liegt – und nichts darüber hinaus.

Least Privilege als Profil

Capabilities sind pro Fenster als benanntes Sicherheitsprofil gesetzt, etwa local-workspace oder account-settings. Ein pauschales fs:* oder shell:* lässt den Build scheitern.

Eine Grenze für die KI

MCP macht die Anwendung für den KI-Client steuerbar, den die Nutzerin schon hat. Die Berechtigungsstufen sind read, propose, commit und delete; die beiden letzten brauchen eine Freigabe und eine menschliche Bestätigung.

05 — Zwei Dateien

Der Composition Root und das Manifest.

tests/application.rsRust
let application = ApplicationBuilder::in_memory()
    .clock(Arc::new(FakeClock::new(now)))
    .notifications(Arc::new(RecordingNotificationService::new()))
    .module(PulseModule)
    .build()?;
app.tomlManifest
[origin]
version = "0.2.0"

[product]
id = "dev.casoon.gitbit"
name = "Gitbit"
version = "0.1.0"
description = "GitHub desktop workspace"

[platform]
tray = true
notifications = true
single_instance = true
window_state = true

[security.windows]
main = { profile = "local-workspace" }
settings = { profile = "account-settings" }

[security.process]
allowed_programs = ["code", "cursor", "open", "xdg-open", "git", "github"]
06 — Anwendungen

Vier Produkte, vier Zuschnitte.

Privates Repository

Timbra

Stundenplanung für Schulen, Berufsschulen und Hochschulen. Tauri-Desktop-App mit Svelte-5-Frontend, die die origin-*-Crates im eigenen Repository mitführt statt sie zu beziehen.

TauriSvelte 5Crates mitgeführt
Privates Repository

Avilo

Ressourcenbasierte Termin- und Patientenplanung für Praxen: ein Termin kann mehrere Patienten, mehrere Mitarbeitende und mehrere Ressourcen gleichzeitig belegen. Ebenfalls mit mitgeführten Crates, inklusive origin-ai und MCP über stdio.

Tauriorigin-aiMCP
Privates Repository

Gitbit

GitHub-Arbeitsplatz für den Desktop – Benachrichtigungen, Issues, Pull Requests, Projects und lokale Clones. Bezieht origin-* = "0.2" als reguläre Abhängigkeit von crates.io, inklusive origin-tauri und den Workspace-Adaptern.

crates.ioOrigin 0.2
Privates Repository

Kestrel

Marktdaten-Terminal, das bewusst nur einen Ausschnitt nutzt: origin-domain, origin-app, origin-secrets, origin-secrets-system und origin-manifest – ohne origin-tauri. Der Beleg, dass die Crates einzeln tragen.

Teilmengeohne origin-tauri
07 — Einstieg

Referenz ansehen, Projekt anlegen, Regeln prüfen.

  1. 1Voraussetzungen

    Werkzeuge installieren

    Rust 1.88 oder neuer, Node 22 oder neuer, pnpm 10 oder neuer. Unter Linux kommen die Tauri-Systempakete dazu.

    cargo install tauri-cli --version "^2"
  2. 2Referenz

    Die Referenzanwendung starten

    Baut und startet die Demo: Tray-App mit Hintergrundschleife, gecachtem Read-Model, typisierten Events und nativen Benachrichtigungen.

    pnpm install && cargo xtask demo
  3. 3Neues Projekt

    Produkt aus dem Template anlegen

    Erzeugt ein Projekt aus templates/app, das die veröffentlichten origin-*-Crates als reguläre Abhängigkeiten nutzt.

    cargo xtask new my-app --name "My App" --id dev.example.myapp
  4. 4Prüfen

    Die Regeln durchsetzen

    ci führt fmt, clippy, Tests, den Abgleich der generierten Dateien und validate aus – dieselben Schritte wie in der CI.

    cargo xtask ci

Entwicklungsstand · Stand: September 2026

Umgesetzt

Plattform und Referenzanwendung

Architekturvertrag, Plattform-Contracts, Tauri-Host-Schicht, OAuth mit PKCE, Kontenverwaltung, Connector-Vertrag, Sync-Engine, Hintergrund-Jobs, Workspace- und Prozess-Contracts samt Adaptern, MCP über stdio und authentifiziertes Loopback-HTTP, das App-Manifest mit generierten Capabilities – und eine laufende Referenzanwendung.

In Arbeit

Version 0.2.0, vor 1.0

Die Crates liegen unter 0.2.0 auf crates.io, die Frontend-Pakete unter demselben Stand auf npm. Vor 1.0 können sich Contracts ändern; cargo xtask update führt die Migrationen zwischen zwei Origin-Versionen aus und gibt eine Checkliste für alles zurück, was nur ein Mensch entscheiden kann.

Offen

Verteilung

Im Template liegt ein tag-gesteuerter Release-Workflow, der standardmäßig unsigniert baut und im Log benennt, was das Artefakt ist. Ende-zu-Ende nachgewiesen ist davon nichts – es gibt noch kein signiertes Produkt. In-App-Updates sind im Manifest aus Sicherheitsgründen abgeschaltet, solange kein Signaturschlüssel existiert.

08 — Grenzen

Was Origin nicht ist.

Origin nimmt einer Anwendung Entscheidungen ab, die sich wiederholen. Es nimmt ihr nicht die Arbeit an ihrem eigenen Gegenstand ab.

Kein Ersatz für Tauri

Tauri bleibt der Host mit seinen Plugins, seiner Webview und seinem Build. Origin ordnet nur, wo welche Schicht liegen darf.

Keine fertigen Features

Es gibt keine mitgelieferte Oberfläche und keine Fachlogik. Was das Produkt kann, schreibt das Produkt – Origin liefert die Verträge darunter.

Vor 1.0

Version 0.2.0 ist eine frühe Version. Contracts können sich ändern, auch wenn die Migrationen gegen eingefrorene Fixture-Projekte getestet sind.

Verteilung ist Vorbereitung

Signierung, Notarisierung und In-App-Updates sind im Template angelegt, aber nie end-to-end durchlaufen. Wer heute ausliefern will, rechnet mit eigener Arbeit an dieser Stelle.

Desktop, nicht Web oder Mobile

Die Plattform-Contracts beschreiben Desktop-Fähigkeiten: Keychain, Tray, Dateisystem, lokale Prozesse. Für Web- oder Mobile-Ziele ist das der falsche Zuschnitt.

09 — FAQ

Häufige Fragen.

Muss ich alle origin-Crates übernehmen?

Nein. Die Crates sind einzeln auf crates.io veröffentlicht und bewusst kontextfrei geschnitten. Kestrel nutzt zum Beispiel nur origin-domain, origin-app, origin-secrets, origin-secrets-system und origin-manifest und verzichtet auf origin-tauri.

Wie wird die Architekturregel durchgesetzt, dass Domain-Code kein Tauri kennt?

Durch cargo xtask validate. Der Task prüft die Abhängigkeitsrichtung zwischen crates/, adapters/, host/ und examples/, verbietet pauschale fs:*- und shell:*-Capabilities und stellt sicher, dass jedes Kommando, das das Frontend beim Namen ruft, auch als #[tauri::command] existiert. Derselbe Task läuft in der CI.

Was passiert bei einem Update auf eine neue Origin-Version?

Jedes Projekt hält in app.toml fest, welcher Origin-Version es folgt. cargo xtask update führt die Migrationen zwischen dieser und der aktuellen Version aus, generiert die Origin-eigenen Dateien neu und gibt eine Checkliste für die Punkte zurück, die eine Entscheidung brauchen. Die Migrationen sind gegen eingefrorene Fixture-Projekte getestet.

Wie hängen Frontend und Rust-Kern zusammen?

Über @casoon/origin-client, das einzige Paket, das Tauri-IPC kennt. Die TypeScript-Typen für Plattform-IPC und für die Kommando-Ergebnisse eines Produkts werden aus den Rust-Definitionen erzeugt, nicht parallel gepflegt. Eine Umbenennung in Rust lässt die CI scheitern statt im Betrieb als undefined aufzutauchen.

Welche Rolle spielt MCP?

MCP ist in Origin ein gleichberechtigter Driving-Adapter neben dem Tauri-Host: Die Anwendung stellt Werkzeuge bereit, die ein externer KI-Client aufrufen darf. Die Berechtigungsstufen sind read, propose, commit und delete, voreingestellt sind die lesenden. Verändernde Aufrufe brauchen eine explizite Freigabe und eine menschliche Bestätigung; fehlt oder scheitert sie, wird der Aufruf abgelehnt.

Darf ich von einer Empfehlung abweichen?

Ja, aber nicht stillschweigend. Eine Abweichung gehört entweder unter [origin.overrides] ins App-Manifest oder als ADR in adr/. Neue Abstraktionen folgen der Promotion Rule aus ADR-0009: Eine Funktion entsteht dort, wo sie gebraucht wird, und wandert erst in die Plattform, wenn eine wirklich neutrale Form erkennbar ist – in der Praxis beim dritten Vorkommen.

Einmal entscheiden, wo welche Schicht liegt.

Origin ist offen, MIT-lizenziert und liegt vollständig auf GitHub – mit Referenzanwendung, Template und 31 Entscheidungsprotokollen.