A native iOS client for self-hosted TriliumNext note-taking servers.
- Connect with the same web session as Trilium (password + cookies + CSRF), not ETAPI
- Browse the full note tree with lazy loading and proper clone/branch semantics
- Read text notes (HTML), code notes, image notes, and file notes
- Search full-text across all notes via the server search API
- Edit note titles, content (HTML source or code), create/delete notes
- Attachments — upload from Photos/Files, download, share
- Offline cache — tree structure and recently opened notes cached locally
- Multiple servers — save and switch between server profiles
- Dark mode and numerous color options
- iOS 17.0+
- Xcode 16.0+
- Swift 5.9+
- A self-hosted TriliumNext server (v0.95.x recommended; native
/apiroutes are pinned inlocal_notes/trilium_native_api_v0.95.md)
This project uses XcodeGen to generate the .xcodeproj:
brew install xcodegen
cd Trinote
xcodegen generateopen Trinote.xcodeproj- Open the project settings
- Select the Trinote target
- Under Signing & Capabilities, set your development team
- Adjust the bundle identifier if needed
Select an iOS 17+ simulator or device and press Cmd+R.
- Enter your server URL (same origin you use in the browser)
- Enter your Trilium password (same as the web UI)
- Optional: Remember me — matches Trilium’s longer-lived session cookie
- TOTP / SSO: complete login in the browser first if your server requires it
If your server uses a self-signed certificate, you'll need to install and trust the CA certificate on your iOS device first (Settings → General → VPN & Device Management). The app allows arbitrary HTTP loads via ATS to support local networks.
Trinote/
├── App/ # App entry, state, tab navigation
├── Core/
│ ├── API/ # TriliumClient (session + `/api`), models, WebSocket
│ ├── Models/ # Domain models, SwiftData cache models
│ ├── Persistence/ # SwiftData container, cache manager
│ ├── Security/ # Keychain token storage
│ └── Utilities/ # Logger, extensions
├── Features/
│ ├── Auth/ # Login, server profile management
│ ├── Tree/ # Note tree browsing
│ ├── Search/ # Full-text search with recents
│ ├── NoteDetail/ # Note viewing, editing, renderers
│ ├── Attachments/ # Photo/file upload
│ └── Settings/ # Settings, recents list
└── Resources/ # Info.plist, Assets
- Native
/api+ sync — session cookies,sync/check+sync/changed, entity-change cursor; WebSocket debounces incremental sync - Notes ≠ Branches — notes and branches are separate entities; a note can appear in multiple tree locations (clones)
- Lazy tree loading — fetches children on demand to avoid loading the entire tree upfront
- Cache-first offline — falls back to cached data when the server is unreachable
- No embedded server — pure client that talks to your existing Trilium server
Run tests in Xcode (Cmd+U) or from the command line:
xcodebuild test -scheme Trinote -destination 'platform=iOS Simulator,name=iPhone 16'Tests cover:
- API client (mock URLProtocol, request/response validation)
- Keychain save/load/delete
- Domain model mapping (notes, branches, attributes, tree nodes)
- Clone semantics (multi-parent notes)
- Error classification (auth, network, server errors)
- Text editing includes many toolbar options mirroring the desktop and browser applications
- Canvas/Mermaid/GeoMap notes show a placeholder image of the diagram.
- Protected notes are able to be read (when password is entered) but not generated on this client
- Background sync — data refreshes in the background and on pull-to-refresh. When starting out manually do a full-sync.
- Search is server-side only — no offline full-text search. Can jump to text references
This project is not affiliated with TriliumNext. It is a community-built iOS client.