
Schnack — Private Messenger
A complete messenger stack from a single pair of hands: native apps, a source-available server, end-to-end encryption all the way into the call signaling, and real-time games. Built AI-natively, with no appetite for data
June 2026
Project
Schnack —
Private Messenger
Schnack —
Open Source Server
Technologies Used
Challenge
Messengers are among the most demanding categories of software there are: real-time communication, cryptography, audio/video calling, push notifications, media processing and offline capability all have to work together seamlessly across multiple platforms. That is exactly why I wanted to build one, as a personal product, as a full-stack technical exercise, and as another proving ground for my AI-native development process.
The ambition: a messenger that deliberately pushes back against the zeitgeist. No feed, no channels, no “discover” tab, no tracking, no ads. Just the people you actually know. And uncompromisingly private.
That translated into four hard requirements:
- End-to-end encryption for everything: messages, photos, videos, files, locations, all the way to call signaling; the server must never be able to read content (server-blind)
- Native apps for iOS and Android with an identical crypto wire format, plus a web companion: three clients, one protocol
- Real-time as a core principle: delivery, read receipts, typing indicators, calls and even games like backgammon run live over the same infrastructure
- Openness instead of lock-in: the server has to be self-hostable, and the apps must work with arbitrary instances
Solution
I designed and built Schnack as a complete stack: server, iOS app, Android app and web messenger. Four guiding principles shaped the architecture.
Encryption without compromise
Every message is encrypted individually per recipient: Curve25519 key exchange, AES-GCM-256 for the content, HKDF for key derivation. Private keys never leave the device, secured in the Keychain on iOS and in the KeyStore on Android. Media is encrypted before upload with its own media key, which in turn only ever travels in encrypted form. For device migration there is a password-protected key backup that lets you decrypt your entire history on a new device.
Native instead of cross-platform
The iOS app is built in SwiftUI with SwiftData persistence, the Android app in Kotlin with Jetpack Compose, both against the same API and crypto wire format. That costs double the work up front, but it pays off in feel, performance and platform integration (APNs/FCM push, photo picker, Keychain/KeyStore). A web messenger with QR code login complements the apps as a desktop companion.
Real-time as the foundation
The server, a Next.js custom server with Socket.io, Prisma and PostgreSQL, treats everything as a real-time event: messages, online presence, typing indicators, read receipts. On the same foundation, complete games run right inside the chat, move by move, live between devices: backgammon with a doubling cube, Othello, and Schnake, a snake score duel. And the same socket layer also carries the call signaling.
Calls and location, encrypted to the edge
Even the features where other messengers tend to compromise stay true to the server-blind principle: 1:1 audio and video calls run over WebRTC (peer-to-peer where possible, TURN relay otherwise), and even the signaling, meaning SDP and ICE candidates, is end-to-end encrypted per recipient; the server merely relays, without ever seeing plaintext. The same goes for location sharing: whether a one-off snapshot or a live location for 15 minutes up to 8 hours, the coordinates never reach the server unencrypted. Both work on all three clients, iOS, Android and the web messenger, with the map preview rendering natively on each (MapKit, osmdroid, Leaflet).
Implementation
AI-native, with a classic safety net
The development process itself is part of the project: Schnack is built AI-natively. Planning happens with maximum reasoning, implementation with Claude Code in Ultracode mode: Fable orchestrates and decomposes the task, Opus agents implement, Fable signs off, and audit rounds keep running until it is right. To make that hold, the safety net is deliberately classic: unit and end-to-end tests plus countless mutation tests verify not just that the code works, but that the tests actually pin it down. The result: in 99% of cases a change goes through the automated deploy pipeline without manual intervention. The human decides the what, the safety net decides the whether.
Open source with a clean derivation
At the end of that pipeline stands the release, and it is open source: the server is source-available (Elastic License 2.0), without the public code becoming a maintenance burden. The public repo is the single source of truth for the server code; my private operations repo, which I use to run a production chat server myself, is a clone of it plus a purely additive overlay (website, legal pages, operational specifics). No shared file ever diverges, upstream merges stay conflict-free, and the public gets exactly the code I run in production. A git tag triggers GitHub Actions, which build a multi-arch Docker image (amd64 + arm64) on native runners and publish it to the GitHub Container Registry. Self-hosting is a one-liner: an interactive install script asks for domain and admin, generates secrets and spins up the stack of app, PostgreSQL and Caddy with auto-HTTPS; migrations and admin bootstrap run automatically. And self-hosted instances are not second-class citizens: the apps support multi-server and multi-account, multiple server profiles switchable with a tap, with strictly separated session, crypto identity and cache per server.
Results
Schnack is released and in use, as a complete product from the protocol through the open server all the way to the App Store release:
- Live in the Apple App Store, Android as a direct APK download, web messenger as a desktop companion
- End-to-end encryption throughout for messages, media and files: the server stays blind
- 1:1 audio and video calls over WebRTC on all three clients, including end-to-end encrypted signaling
- Location sharing, static and live (15 min to 8 h): coordinates stay end-to-end encrypted
- Three real-time games inside the chat: backgammon, Othello and Schnake
- Groups, multi-image messages, video messages, link previews, read receipts and typing indicators
- Source-available server (ELv2) with tag-triggered multi-arch builds (GitHub Actions → GHCR) and a one-liner installer for self-hosting
- Multi-server & multi-account in the apps: separate session, crypto identity and cache per server, switchable with a tap
- No tracking, no ads, no data trading, completely free
The project shows the full range: protocol design and cryptography, two native apps plus a web client, a real-time backend with WebRTC calling, push infrastructure, a source-available release process with an automated pipeline, and an AI-native development workflow that makes this breadth possible as a one-person project in the first place.