A private, self-hosted, end-to-end encrypted note-taking app.
One owner, many devices. The server stores only ciphertext.
Website · Docs · Protocol · Changelog · Contributing
Platforms: Android (F-Droid), Linux desktop, Windows desktop
Pick one Android source and stay with it. F-Droid and GitHub Release APKs are signed by different keys, so an update from the other source will not install over your current copy (uninstall + reinstall is the only way to switch). The app shows a one-time note about this on the Sync page.
Grab a package from the latest release:
| Distro | Package |
|---|---|
| Arch | librenotes-bin on the AUR: yay -S librenotes-bin |
| Debian / Ubuntu | .deb: sudo apt install ./LibreNotes-<version>-amd64.deb |
| Fedora / openSUSE | .rpm: sudo dnf install ./LibreNotes-<version>-x86_64.rpm |
| Any | .AppImage (chmod +x, then run) or the .tar.gz bundle |
.deb and .rpm also come in arm64 / aarch64.
Most note apps make you choose between convenience and control. LibreNotes is built so you don't have to.
- Your server, your data. Sync runs on a small server you host yourself, on a home LAN or a Tailscale/WireGuard mesh. There is no account, no vendor cloud, and nothing is sent to the developer.
- The server can't read your notes. Everything is encrypted on your device before it leaves, so the server only ever holds ciphertext. A new device needs only your passphrase to unlock.
- Works fully offline. Every device keeps a local, encrypted store and syncs whenever the server is reachable. The app never waits on the network.
- You decide conflicts. There is no CRDT magic. If two devices edit the same note, you see both versions and pick the winner.
- Plain markdown, no lock-in. Notes are ordinary markdown, and you can
export them all as
.mdfiles at any time. - Genuinely free software. AGPLv3, no trackers, no Google Play Services, and no Electron. The desktop app is native Flutter.
- Markdown notes with live preview
- Dark theme, orange accent, resizable sidebar
- Offline-first: full local cache, syncs opportunistically
- End-to-end encryption (XChaCha20-Poly1305 + Argon2id key derivation), plus encryption of notes at rest on each device
- Conflict resolution: server detects stale writes and returns both versions; you pick the winner
- Archive, and a trash bin with restore and permanent delete
- Text highlighting, custom and gradient note colors
- Self-destructing notes, and quick capture with a global hotkey on Linux
- Markdown import and export
- Self-hosted sync server (Shelf + SQLite, single compiled binary or Docker image)
packages/notally_core/ Shared Dart models + sync DTOs (app + server)
server/ Sync server (Shelf + SQLite, E2EE-blind)
clients/app/ Flutter client (Android, Linux desktop, web)
assets/icon/ Source app icon
cd server
dart pub get
dart run bin/server.dartThe server prints a bearer token on first start and binds to 0.0.0.0:8787.
See server/README.md for full configuration and API docs.
cd clients/app
flutter pub get
flutter run -d linux # Linux desktop
flutter run -d chrome # web
flutter run # Android (device/emulator attached)The Flutter SDK must be on PATH:
export PATH="$PATH:/path/to/flutter/bin"See clients/app/README.md for build instructions.
The server is LAN-only by design. For access away from home, join devices and the server on a Tailscale or WireGuard mesh and update the server URL in the app — no server code change needed. Never expose the server directly to the WAN.
The server speaks plain HTTP. To add TLS, put a reverse proxy in front of it and
set NOTALLY_HOST=127.0.0.1 so only the proxy can reach it. Use a certificate
your devices trust, then enter the https:// address as the Server URL.
- Tailscale:
tailscale serve --bg 8787serves it athttps://<machine>.<tailnet>.ts.net(enable HTTPS certificates in the admin console first). - Caddy:
notes.example.com { reverse_proxy 127.0.0.1:8787 } - nginx:
proxy_pass http://127.0.0.1:8787;inside a TLSserverblock.
Full examples are in the sync docs. HTTPS doesn't make it safe to expose the server to the public internet.
- All encryption and decryption happens on the client. The server never sees plaintext, keys, or passphrases.
- Each note is encrypted with a random DEK (XChaCha20-Poly1305, per-write nonce). The DEK is wrapped with a key derived from the user's passphrase via Argon2id. The wrapped DEK lives on the server; the passphrase never leaves the device.
- Conflict detection runs on
rev(plaintext metadata), not content.
To report a vulnerability, see SECURITY.md.
Bug reports, ideas and pull requests are welcome. Start with CONTRIBUTING.md, and please follow the Code of Conduct.
AGPLv3 — see LICENSE. AGPL is intentional: this is a network server application.

