Architecture
This document describes Skelenote's system architecture, data flow, and key design decisions.
High-Level Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ Skelenote App │
├─────────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ React Frontend (TypeScript) │ │
│ │ ┌─────────────────────────────────────────────────────────┐│ │
│ │ │ React Context Providers ││ │
│ │ │ ObjectContext │ NavigationContext │ SyncContext │ ... ││ │
│ │ └─────────────────────────────────────────────────────────┘│ │
│ │ ┌─────────────────────────────────────────────────────────┐│ │
│ │ │ Core Libraries ││ │
│ │ │ LoroDocStore │ ObjectStore │ SyncClient │ CryptoWrapper ││ │
│ │ └─────────────────────────────────────────────────────────┘│ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ invoke() │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Tauri Backend (Rust) │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │ │
│ │ │ Crypto │ │ Network │ │ Device Management │ │ │
│ │ │ (XChaCha20) │ │ (mDNS + TCP) │ │ (Ed25519 Sigs) │ │ │
│ │ └──────────────┘ └──────────────┘ └──────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
│ │
▼ ▼
┌───────────────┐ ┌───────────────┐
│ Local Disk │ │ Local Network │
│ (Loro + Keys) │ │ (P2P Peers) │
└───────────────┘ └───────────────┘React Context Hierarchy
Contexts provide shared state and operations across the app:
Context Responsibilities
ThemeContext
Dark/light mode state, color scheme
useTheme()
ToastContext
Toast notifications, user feedback
useToast()
SkeletonKeyContext
Skeleton Key state, initialization, unlock
useSkeletonKey()
ObjectContext
CRUD operations on objects, CRDT store
useObjects()
SyncContext
Cloud relay WebSocket sync
useSync()
LocalSyncContext
P2P local network sync, QR pairing
useLocalSync()
DeviceRegistryContext
Device list, revocation, trust
useDeviceRegistry()
NavigationContext
View state, split pane, routing
useNavigation()
SidebarContext
Sidebar collapse/expand state
useSidebar()
KeyboardShortcutsContext
Global hotkey registration
useKeyboardShortcuts()
UndoContext
History navigation, time machine
useUndo()
SemanticSearchContext
Vector embeddings, similarity search
useSemanticSearch()
Repository Structure
Data Model
SkelenoteObject
Everything in Skelenote is a typed object:
Built-in Types
Defined in src/lib/types/built-in-types.ts:
Task - With status, due date, priority
Note - General purpose notes
Project - Container for tasks/notes
Area - Long-term responsibility area (PARA)
Link - Web bookmarks
Meeting - Calendar events
Tag - Labels for categorization
Person - Contact references
Template - Reusable object templates
Object Relations
Objects can link to each other via the relation property type:
Data Flow
Object CRUD Flow
Sync Flow
CRDT Strategy
Skelenote uses Loro for conflict-free sync:
Why Loro?
Automatic merge - No manual conflict resolution
History built-in - Time travel via versioning
Efficient sync - Only transmits deltas
Rich types - Map, List, Text, Tree
Document Structure
Conflict Resolution
Loro uses CRDT semantics:
Last-writer-wins for primitive properties
List operations merge by causal order
Text operations use collaborative editing algorithm
Encryption Architecture
Key Hierarchy
Data at Rest
Loro document - Not encrypted on disk (local-first philosophy)
Master key - Stored in Stronghold (OS keychain)
Device ID - Persisted in Stronghold
Data in Transit
All sync data is encrypted with XChaCha20-Poly1305:
Frontend calls
crypto_encryptwith Loro update bytesEncrypted bytes sent to relay/peers
Receiver calls
crypto_decryptto get Loro updatesLoro imports the decrypted updates
P2P Networking
Discovery
Skelenote supports two discovery methods:
mDNS (automatic, same network)
Device advertises
_skelenote._tcp.local.Service name includes: device ID, device name, fingerprint
Other devices discover via mDNS browse
Fingerprint (derived from user ID) enables filtering to same-vault peers
QR Code Pairing (cross-network, mobile-friendly)
One device generates a pairing code containing connection info and a one-time key
Code displayed as QR code or copyable text
Second device scans QR or enters code manually
Devices establish direct connection using the shared secret
After initial pairing, devices can sync via mDNS on the same network
Connection
TCP connection to discovered peer
Handshake exchanges device info + fingerprint
Fingerprint mismatch = different vault = reject
Connected peers exchange Loro updates bidirectionally
Device Revocation
Revoking device signs revocation with Ed25519
Signature + metadata broadcast to all peers
Revoked device added to local blocklist
Blocklist persisted to disk and checked on:
mDNS discovery (filter out)
TCP handshake (reject)
Connection attempt (refuse)
Mobile Architecture
Skelenote supports iOS and Android via Tauri 2.0's mobile capabilities.
Platform Structure
Mobile Components
Mobile-specific UI components live in src/components/mobile/:
primitives/
Touch-optimized base components (buttons, inputs)
rows/
List row components for mobile lists
sheets/
Bottom sheet views (settings, object details)
skeletons/
Loading skeleton states
views/
Full-screen mobile view layouts
Platform Detection
Use Tauri's platform detection to conditionally render mobile vs desktop UI:
Mobile-Specific Considerations
Touch targets: Minimum 44x44pt for iOS, 48x48dp for Android
Bottom sheets: Replace modals with swipeable bottom sheets
Gesture navigation: Support swipe-back and pull-to-refresh
Share extension: Handle incoming shares via
src/lib/share/Safe areas: Account for notches, home indicators, and status bars
File System Layout
macOS
Windows
Linux
iOS
Android
Key Design Decisions
Local-First
All data lives on the user's device. Sync is optional and additive.
Zero-Knowledge Encryption
The relay server never sees plaintext. Only devices with the Skeleton Key can decrypt.
CRDT for Collaboration
Loro CRDTs enable offline-first with automatic conflict resolution.
Rust for Security
Cryptographic operations in Rust via Tauri for memory safety and performance.
PARA by Default
Built-in structure (Projects, Areas, Resources, Archive) with flexibility to customize.
Cross-Platform from Day One
Tauri 2.0 enables a single codebase for desktop (macOS, Windows, Linux) and mobile (iOS, Android).
Last updated