A private, decentralized messenger built on Nostr using the Marmot protocol for MLS group encryption, with identity based on keypairs. Phone and email play no role in the system.
This is the Flutter app. The core messaging library and CLI live in whitenoise-rs.
Encrypted group messaging. White Noise uses MLS (Messaging Layer Security) for group chats, with forward secrecy and post-compromise security built in.
Keypair identity. Accounts are keypairs. Create one in the app or import your own. Phone numbers and email addresses play no part in this.
Decentralized transport. Messages route through Nostr relays. The architecture is serverless by design: any relay can carry your messages.
External signer support. Works with Amber and other NIP-55 signers. Your private key stays out of the app entirely.
Media. Send images and video with blurhash previews while loading. Attachments are encrypted at rest on device.
Search and conversation management. Find messages across all groups from a single search. Block or mute contacts, or archive entire chats.
Multi-account with encrypted local storage. Switch identities freely. App data is encrypted on device, and the local database migrates automatically on upgrade.
Open source. Released under the AGPL-3.0 license.
| Platform | Status |
|---|---|
| Android | Supported |
| iOS | Supported |
| macOS | Planned |
| Windows | Planned |
| Linux | Planned |
| Web | Planned |
| Layer | Technology |
|---|---|
| UI | Flutter (>=3.41.4) |
| Core | Rust via whitenoise-rs |
| FFI | flutter_rust_bridge |
| Protocol | Marmot (MLS over Nostr) |
- Flutter SDK (3.41.4 or later)
- Rust (latest stable)
- Just:
cargo install just flutter_rust_bridge_codegen:cargo install flutter_rust_bridge_codegen
just deps # Install Flutter and Rust dependencies
just run # Run on a connected device (staging flavor)lib/
├── constants/ # Fixed, shared values
├── providers/ # Shared app state (Riverpod)
├── hooks/ # Ephemeral widget state
├── services/ # Stateless operations
├── screens/ # Full-page components
└── widgets/ # Reusable components
The rust/ directory holds a thin Rust crate that wraps whitenoise-rs and generates the Flutter bridge bindings.
just deps # Install Flutter and Rust dependencies
just run # Run on a connected device (staging)
just format # Format Rust and Dart code
just lint # Run Rust clippy and Flutter analyzer
just test-flutter # Run Flutter tests
just test-rust # Run Rust tests
just precommit # Full pre-commit check (format, lint, test)
just coverage # Check test coverage (minimum 99%)
just build-android # Build Android APK
just build-ios # Build Rust libs for iOSRun just with no arguments to see all available commands.
- Keep complexity low. Keep the app thin.
- The whitenoise-rs crate is the source of truth. Avoid caching in Flutter.
- Shared app state goes in providers. Ephemeral widget state goes in hooks.
- Screens watch providers and pass data down to hooks.
- Test coverage must stay at 99% or above.
- Delete dead code. Commented code is dead code.
- Write self-explanatory code. Comments are for the non-obvious.
The repo includes a Widgetbook for developing and reviewing UI components in isolation.
just widgetbook-macos # Run on macOS
just widgetbook-linux # Run on LinuxRead CONTRIBUTING.md before opening a PR. The short version: fork the repo, open or comment on an issue before building significant features, keep PRs under ~500 lines, always run just precommit, and include screenshots for UI changes.
See the releases page for changelogs and APK downloads.
- Marmot protocol spec
- whitenoise-rs: Rust core library and CLI
- Flutter docs
- whitenoise.chat
White Noise is free and open source software, released under the AGPL-3.0 license.
