Die Familien-App, die uns keiner verkaufen wollte
Du willst einfach nur wissen, wer diese Woche das Bad putzt, was noch eingekauft werden muss und wann das Kind zum Sport gebracht werden soll — und am Ende hast du fünf verschiedene Apps, drei WhatsApp-Gruppen und trotzdem vergisst jemand den Termin beim Zahnarzt.
Mein Familien Planer ist eine iOS-App, die ich für meine eigene Familie baue. Kein Startup, kein Abo-Modell, keine Cloud-Abhängigkeit. Einfach eine App, die das Familienchaos in den Griff kriegt.
Support: mario [at] xenji [punkt] com
Warum nehme ich Geld dafür und warum kein OpenSource?
Ich muss irgendwie meine Apple Developer License gegenfinanzieren und finde einmalige 0,99 EUR fair, gegeben, dass ich nicht alles davon sehen werde. OSS ist immer toll. Ich will aber, dass es "meine" App bleibt, nicht aus Eigentumsperspektive sondern vom Featureset und der Projektidee. Ich denke, dass ich das am Besten kann, wenn ich die Entwicklung selbst und allein vorantreibe.
Was kann die App?
Gemeinsamer Kalender
Der Familienkalender zeigt alle Termine aller Familienmitglieder auf einen Blick — farblich nach Person kodiert. Monats-, Wochen- und Listenansicht, wiederkehrende Termine (RFC 5545), und Import aus dem Apple-Kalender.
Aufgabenlisten
Geteilte To-Do-Listen mit drei Modi: "Jeder" (alle sehen es, jeder muss abhaken), "Zugewiesen" (einer ist verantwortlich) oder "Irgendwer" (wer es zuerst erledigt, hat gewonnen). Prioritäten, Fälligkeitsdaten und Wiederholungen inklusive.
Putzplan
Der Klassiker. Räume, Aufgaben und Zuständigkeiten — alles konfigurierbar. Wer ist diese Woche für in der Küche dran?
Einkaufsliste
Getrennt von den To-Dos, weil Einkaufen sein eigenes Ding ist. Artikel lassen sich nach Laden sortieren (Lidl, REWE, etc.), und beim Einkaufen zeigt die App nur die Artikel für den aktuellen Laden an. Abgehaktes lässt sich mit einem Tap löschen.
Familienverwaltung
Ein Familienmitglied lädt die anderen ein. Jedes Mitglied bekommt eine Farbe, und man kann auswählen, wen man zusätzlich noch verwalten will. Praktisch, wenn man als Elternteil ein Kind ohne Handy managen will oder muss.
Warum selbst bauen?
Die ehrliche Antwort: Weil ich es kann und weil mir keine existierende App gefallen hat. Die meisten Familien-Apps wollen entweder ein Abo, schieben alles in irgendeine Cloud, oder sehen aus wie 2015.
Offline-First und Self-Hosted Sync
Die App funktioniert komplett ohne Internet. Alle Daten liegen lokal auf dem Gerät in einer eingebetteten Datenbank (Couchbase Lite). Wer möchte, kann optional einen eigenen CouchDB-Server aufsetzen und die Daten zwischen den Geräten der Familie synchronisieren. Kein Apple-Cloud-Lock-in, keine fremden Server, keine Abhängigkeit von Diensten, die nächstes Jahr vielleicht eingestellt werden.
Die Sync-Engine ist netzwerk-aware — sie pausiert automatisch, wenn kein Internet da ist, und setzt fort, sobald die Verbindung steht. Konflikte werden über Three-Way-Merge aufgelöst, also gehen keine Daten verloren, selbst wenn zwei Leute gleichzeitig offline etwas ändern.
Datenschutz
Keine Telemetrie, keine Analytics, kein Account-Zwang. Die App weiss nicht mal, dass es mich gibt — das ist so gewollt.
CouchDB selbst hosten
Wer die Sync-Funktion nutzen will, braucht eine laufende CouchDB-Instanz. Das klingt erstmal nach viel Aufwand, ist mit Docker aber in ein paar Minuten erledigt. Die Anleitung hier orientiert sich an einem Setup-Guide aus der Obsidian LiveSync Community, die CouchDB für ein ähnliches Offline-First-Sync-Szenario nutzen.
Voraussetzungen
- Ein Server mit Docker und Docker Compose (ein kleiner VPS bei Hetzner, Netcup, Scaleway, etc für ein paar Euro im Monat reicht völlig). Ich hoste meine auf einem alten Laptop zu Hause mit Tailscale VPN.
- Eine Domain oder Subdomain mit HTTPS (z.B. über Caddy oder Traefik als Reverse Proxy)
Docker Compose
Erstellt eine docker-compose.yml:
services:
couchdb:
image: couchdb:3
restart: unless-stopped
environment:
COUCHDB_USER: admin
COUCHDB_PASSWORD: ein-sicheres-passwort-hier
volumes:
- couchdb_data:/opt/couchdb/data
- ./local.ini:/opt/couchdb/etc/local.d/local.ini
ports:
- "5984:5984"
volumes:
couchdb_data:CouchDB Konfiguration
Legt eine local.ini neben der docker-compose.yml an:
[chttpd]
bind_address = 0.0.0.0
max_http_request_size = 4294967296
[httpd]
enable_cors = true
[cors]
origins = *
credentials = true
methods = GET, PUT, POST, HEAD, DELETE
headers = accept, authorization, content-type, origin, referer
[chttpd_auth]
require_valid_user = true
[couchdb]
single_node = true
max_document_size = 50000000Starten und einrichten
docker compose up -dDanach CouchDB als Single Node initialisieren:
curl -X POST http://admin:ein-sicheres-passwort-hier@localhost:5984/_cluster_setup \
-H "Content-Type: application/json" \
-d '{"action":"finish_cluster"}'Die Datenbank für die App anlegen:
curl -X PUT http://admin:ein-sicheres-passwort-hier@localhost:5984/family-appFertig. In den App-Einstellungen trägt man dann die URL (https://deine-domain.de/family-app), Benutzername und Passwort ein, und die Sync-Engine übernimmt den Rest.
HTTPS nicht vergessen
CouchDB selbst spricht nur HTTP. Für den Betrieb übers Internet braucht ihr einen Reverse Proxy davor, der TLS terminiert. Caddy ist dafür am einfachsten — ein Caddyfile mit zwei Zeilen reicht:
couchdb.deine-domain.de {
reverse_proxy localhost:5984
}Caddy holt sich automatisch ein Let's-Encrypt-Zertifikat. Alternativ tut es auch Träfik oder nginx mit certbot.
Andere Wege
Es muss kein eigener Server sein. CouchDB lässt sich überall betreiben, wo Docker-Container laufen — ob bei einem Cloud-Anbieter eurer Wahl, auf einem Raspberry Pi im Keller oder sonstwo. In der Obsidian LiveSync Community gibt es beispielsweise eine Anleitung für ein Fly.io-Deployment mit Dockerfile und persistentem Volume. Das ist keine Empfehlung für Fly.io im Speziellen — nur ein Beispiel dafür, dass das Setup auf verschiedenen Plattformen funktioniert.
Tech-Stack
Für die technisch Interessierten:
- Swift 6.0 mit striktem Concurrency-Checking (Xcode 16+)
- SwiftUI für die gesamte UI
- Couchbase Lite 4.0 als eingebettete Datenbank
- CouchDB für optionalen Self-Hosted-Sync
- EventKit für Apple-Kalender-Integration
- MapKit / CoreLocation für Orte in Kalendereinträgen
Die Architektur folgt einem modularen Ansatz mit sauberer Trennung: Domain-Schicht (Protokolle und Value Types), Data-Schicht (Persistenz und Sync) und Feature-Module für jede Funktionsgruppe. Jedes Feature ist ein eigenes Swift Package.
Concurrency
Swift 6 mit striktem Concurrency ist kein Spass — aber es garantiert zur Compile-Zeit, dass es keine Race Conditions gibt. ViewModels sind @MainActor @Observable, Repositories ebenfalls @MainActor, und alles, was tatsächlich über Thread-Grenzen geht, ist explizit markiert und abgesichert.