A decentralized peer-to-peer social network built with Iroh, Tauri 2, and SvelteKit 5.
Successor to follow and identia, rebuilt on iroh's QUIC transport with end-to-end encrypted messaging.
Every user runs their own node. Posts, profiles, and follows are stored locally. Peers exchange data directly -- no central server, no accounts, no passwords. Optional discovery servers provide search, trending, and user directories without compromising the P2P foundation.
Each node has a three-tier key hierarchy:
master_key.key. Your master public key is what others follow. The master key signs delegations and key rotations but never signs content directly. On first launch, a 24-word BIP39 recovery phrase is generated for backup.The master key signs a SigningKeyDelegation binding the signing key to the identity. Peers cache this delegation and verify content signatures against the signing key. This separation means a compromised device's signing key can be rotated without losing the permanent identity.
Four protocol layers handle all communication:
When following a new user, an IdentityRequest is sent to their transport NodeId. The response contains their master pubkey, user key delegation, and profile. This is cached locally so subsequent connections can resolve the master pubkey to reachable transport NodeIds.
All data is persisted in a local SQLite database. The app works offline and syncs when peers are available.
Backend state model: Only the FeedManager (which manages gossip subscriptions) is behind a mutex. All other state -- the Iroh endpoint, blob store, database -- is accessed lock-free, so blob fetches and feed queries never block each other.
npm install
npm run tauri dev
This starts both the Vite dev server (port 1420) and the Tauri backend.
npm run tauri build
Produces a native desktop application in src-tauri/target/release/.
rustup target add aarch64-linux-android armv7-linux-androideabi x86_64-linux-android i686-linux-android
export ANDROID_HOME="$HOME/Android/Sdk"
export NDK_HOME="$ANDROID_HOME/ndk/<version>"
Run on a connected device or emulator:
npm run tauri android dev
To view logs:
adb logcat -s iroh-tauri-app
Use a broader filter if needed (the tag may vary):
adb logcat | grep -i iroh
npm run tauri android build
The APK/AAB is output to src-tauri/gen/android/app/build/outputs/.
tauri-plugin-log which routes to Android logcat automaticallyendpoint.network_change() every 30 seconds to keep connectivity alivetauri-plugin-barcode-scanner which requires the CAMERA permission (declared in the manifest)iroh-social:// schemeA self-hosted, headless server binary (server/) that adds opt-in aggregation, search, and trending to the P2P network. Users register with a server by signing a cryptographic proof of identity. The server subscribes to their gossip topics and indexes their posts in SQLite with FTS5, exposing an HTTP API for search, trending hashtags, user directory, and aggregated feeds.
The server is an overlay -- the P2P layer remains the foundation. Users who never connect to a server lose nothing.
cargo build --release --manifest-path server/Cargo.toml
./server/target/release/iroh-social-server
The server listens on port 3000 by default. Configuration is via environment variables (IROH_SOCIAL_PORT, IROH_SOCIAL_DB_PATH).
A deploy script is provided for uploading to a remote server:
scripts/deploy-server.sh
This builds a static musl binary, uploads it via scp, and restarts the systemd service.
GET /api/v1/info -- Server info (name, version, user/post counts)POST /api/v1/register -- Register with signed cryptographic proofDELETE /api/v1/register -- UnregisterGET /api/v1/feed -- Aggregated post feedGET /api/v1/trending -- Trending hashtagsGET /api/v1/users -- User directoryGET /api/v1/users/search?q= -- Search usersGET /api/v1/users/{pubkey}/devices -- Transport NodeIds for a user's devicesGET /api/v1/posts/search?q= -- Full-text post searchUsers choose a visibility level when registering:
See todos/community-server.md for the full design document.
End-to-end encrypted direct messaging over a custom QUIC protocol (iroh-social/dm/1). E2E encryption uses X25519 key exchange derived from each user's existing ed25519 identity, with a Noise IK handshake for session establishment and a Double Ratchet for per-message forward secrecy. Messages are encrypted such that only the two participants can read them -- not relay servers, not discovery servers, not anyone.
See todos/direct-messaging.md for the original design document.
Peer-to-peer voice and video calls, with call signaling encrypted via the DM ratchet session.
See todos/voice-video-calling.md for the design document.
Link multiple devices (phone, desktop, tablet) to a single identity. The three-tier key hierarchy (master / user / transport) is implemented: a master key is the permanent identity, a derived user key handles signing and DM encryption across all devices, and per-device transport keys provide unique iroh NodeIds. The master key enables secure user key rotation if a device is compromised without losing the identity.
Phase 1 (key hierarchy, identity resolution, delegation) is complete. Remaining phases cover device pairing, multi-device sync, key rotation, and revocation.
See todos/linked-devices.md for the full design document.
VS Code + Svelte + Tauri + rust-analyzer.
MIT