A cross-platform desktop application for decentralized file storage, built with Tauri v2, React, and TypeScript.
WARNING: Alpha Software - Pilot Program
This software is in alpha stage and is part of the pilot program. Do not use this for mission-critical data or personal files that you cannot afford to lose.
- Data loss may occur due to bugs, incomplete features, or network issues
- There is no guarantee of data persistence or recovery
- Always maintain separate backups of important files
- This software is provided "as-is" without warranty of any kind
By using this software, you acknowledge and accept these risks.
- Guided Onboarding: First-run wizard to get your first backup in under 30 seconds
- File Management: Upload, download, and manage files on the decentralized network
- Folder Sync: Watch folders and automatically sync changes to the network
- Backup Server: Automatic continuous backup to designated peers
- Peer Network: Connect with peers, share SPR records, and monitor network stats
- Node Logs: Built-in real-time log viewer with auto-refresh and auto-scroll
- System Tray: Runs in the background with quick access from the system tray
- Auto-Update: Automatic updates from GitHub releases
- Sound Notifications: Audio feedback for node startup, peer connections, and downloads
| Layer | Technology |
|---|---|
| Frontend | React 18 + TypeScript + Vite |
| Backend | Rust + Tauri v2 |
| Sidecar | archivist-node (P2P storage daemon) |
| Package Manager | pnpm v10 |
| Node.js | v20 |
| Rust | 1.77.2+ stable |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Archivist Desktop (Tauri App) β
β β
β ββββββββββββββββββββββ ββββββββββββββββββββββββββ β
β β React Frontend β β Rust Backend β β
β β (Webview) βββββββΊβ (Native Process) β β
β β β IPC β β β
β β β’ Dashboard β β β’ Node Management β β
β β β’ Backups β β β’ File Operations β β
β β β’ Restore β β β’ Folder Watching β β
β β β’ Devices β β β’ Peer Management β β
β β β’ Peers β β β’ Backup Daemon β β
β β β’ Logs β β β’ Configuration β β
β β β’ Settings β β β’ HTTP Client β β
β ββββββββββββββββββββββ βββββββββββββ¬βββββββββββββ β
β β β
ββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββ
β
HTTP (localhost:8080)
β
ββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββ
β archivist-node Sidecar (Separate Process) β
β β
β β’ REST API (port 8080) β
β β’ File Storage & CID Management β
β β’ P2P Network (libp2p) β
β β’ Discovery (DHT/mDNS, UDP port 8090) β
β β’ Listen (TCP port 8070) β
β β’ Peer Connections β
β β’ Data Replication β
ββββββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββ
β
P2P (encrypted)
β
ββββββββββββββΌβββββββββββββ
β External Peers β
β (libp2p network) β
βββββββββββββββββββββββββββ
- User Interface: React frontend provides the UI (Dashboard, Backups, Restore, Devices, Peers, Logs, Settings)
- Tauri Backend: Rust backend handles:
- Starting/stopping the archivist-node sidecar process
- Managing file system operations (uploads, downloads, folder watching)
- Proxying requests to the node's REST API
- Persisting application configuration
- Running the backup daemon for continuous sync
- Archivist Node: Standalone sidecar process that:
- Exposes REST API on localhost:8080
- Manages content-addressed storage (CIDs)
- Handles P2P networking via libp2p
- Discovers peers via DHT/mDNS on UDP port 8090
- Accepts peer connections on TCP port 8070
- Replicates data across the network
- P2P Network: Encrypted libp2p connections between peers for file transfer and discovery
- Node.js 20+
- pnpm v10+
- Rust 1.77.2+ stable
- Platform-specific dependencies for Tauri (see Tauri Prerequisites)
# Quick setup (install deps + download sidecar binary)
pnpm setup
# Or step by step:
pnpm install
pnpm download-sidecar # Downloads archivist-node for your platform
# Run in development mode
pnpm tauri dev
# Build for production
pnpm tauri buildThe sidecar binary must match your target platform. To download for cross-compilation:
# macOS
bash scripts/download-sidecar.sh x86_64-apple-darwin # Intel
bash scripts/download-sidecar.sh aarch64-apple-darwin # Apple Silicon
# Linux
bash scripts/download-sidecar.sh x86_64-unknown-linux-gnu # x64
bash scripts/download-sidecar.sh aarch64-unknown-linux-gnu # ARM64
# Windows
bash scripts/download-sidecar.sh x86_64-pc-windows-msvcarchivist-desktop/
βββ src/ # React frontend
β βββ components/ # Reusable UI components
β β βββ NavAccordion.tsx # Collapsible navigation sections
β β βββ NextSteps.tsx # Post-onboarding guidance
β βββ hooks/ # Custom React hooks
β β βββ useNode.ts # Node lifecycle (start/stop/status)
β β βββ useSync.ts # Folder watching + sync queue
β β βββ usePeers.ts # Peer connections
β β βββ useOnboarding.ts # First-run onboarding state
β β βββ useSoundNotifications.ts # Audio feedback
β β βββ useFeatures.ts # Feature flag detection
β βββ pages/ # Route components
β β βββ Dashboard.tsx # Main status overview
β β βββ Onboarding.tsx # First-run wizard
β β βββ Files.tsx # Upload/download/restore files
β β βββ Sync.tsx # Watched folder management
β β βββ Devices.tsx # Device management
β β βββ AddDevice.tsx # Device pairing wizard
β β βββ Peers.tsx # P2P network view
β β βββ BackupServer.tsx # Backup daemon dashboard
β β βββ Logs.tsx # Node logs viewer
β β βββ Settings.tsx # App configuration
β βββ lib/ # Utilities and types
β β βββ cidValidation.ts # CID format validation
β β βββ tauri.ts # Tauri invoke helpers
β βββ styles/ # CSS files (terminal aesthetic)
β βββ App.tsx # Router + layout
β βββ main.tsx # Entry point
β
βββ src-tauri/ # Rust backend
β βββ src/
β β βββ main.rs # App entry (delegates to lib.rs)
β β βββ lib.rs # Tauri setup, commands, tray
β β βββ error.rs # ArchivistError enum
β β βββ state.rs # AppState (service container)
β β βββ node_api.rs # HTTP client for sidecar
β β βββ commands/ # Tauri command handlers
β β β βββ node.rs # start/stop/restart/status/logs
β β β βββ files.rs # upload/download/list/delete
β β β βββ sync.rs # watch folders, sync queue, manifests
β β β βββ peers.rs # connect/disconnect/list
β β β βββ system.rs # config, platform info
β β βββ services/ # Business logic
β β βββ node.rs # Sidecar process management
β β βββ sync.rs # File watching (notify crate)
β β βββ config.rs # Settings persistence
β β βββ backup_daemon.rs # Backup daemon (polls source peers)
β β βββ manifest_server.rs # HTTP manifest discovery server
β βββ resources/ # Bundled assets (video files)
β βββ sidecars/ # archivist-node binaries (gitignored)
β βββ Cargo.toml # Rust dependencies
β βββ tauri.conf.json # Tauri configuration
β
βββ public/ # Static assets
β βββ logos/ # Branding assets
β
βββ scripts/
β βββ download-sidecar.sh # Downloads archivist-node binary
β
βββ .github/workflows/
β βββ ci.yml # Tests, lint, build checks
β βββ release.yml # Multi-platform release builds
β
βββ package.json # npm scripts + dependencies
- Linux:
~/.config/archivist/config.toml - macOS:
~/Library/Application Support/archivist/config.toml - Windows:
%APPDATA%\archivist\config.toml
| Setting | Default | Description |
|---|---|---|
data_dir |
Platform-specific | Node data directory |
api_port |
8080 |
REST API port |
discovery_port |
8090 |
UDP port for DHT/mDNS peer discovery |
listen_port |
8070 |
TCP port for P2P connections |
max_storage_bytes |
10 GB | Storage quota |
auto_start |
false |
Start node on app launch |
auto_restart |
true |
Restart on failure |
Note: Configuration changes require a node restart to take effect.
| Setting | Default | Description |
|---|---|---|
enabled |
false |
Enable backup daemon |
poll_interval_secs |
30 |
Check for new manifests every N seconds |
max_concurrent_downloads |
3 |
Parallel file downloads |
max_retries |
3 |
Retry failed downloads |
auto_delete_tombstones |
true |
Process file deletions |
The application uses multiple ports for P2P networking and backup functionality:
| Port | Protocol | Purpose | Required On |
|---|---|---|---|
| 8070 | TCP | P2P connections and file transfers | Both machines |
| 8090 | UDP | Discovery via DHT/mDNS | Both machines |
| 8085 | TCP | Manifest server (backup source) | Source machine only |
| 8086 | TCP | Backup trigger endpoint | Backup server only |
Minimum required: Open ports 8070 (TCP) and 8090 (UDP) for basic P2P functionality.
For backup system: Also open 8085 on the source machine and 8086 on the backup server.
# Required for P2P
sudo ufw allow 8070/tcp # P2P connections
sudo ufw allow 8090/udp # Discovery
# For backup source (Machine A)
sudo ufw allow 8085/tcp # Manifest server
# For backup server (Machine B)
sudo ufw allow 8086/tcp # Backup triggerThe firewall will prompt you to allow connections when the app first runs. Click "Allow" to enable P2P connectivity.
# Required for P2P
netsh advfirewall firewall add rule name="Archivist P2P" dir=in action=allow protocol=tcp localport=8070
netsh advfirewall firewall add rule name="Archivist Discovery" dir=in action=allow protocol=udp localport=8090
# For backup source (Machine A)
netsh advfirewall firewall add rule name="Archivist Manifest Server" dir=in action=allow protocol=tcp localport=8085
# For backup server (Machine B)
netsh advfirewall firewall add rule name="Archivist Backup Trigger" dir=in action=allow protocol=tcp localport=8086If you change the ports in Settings β Advanced, update your firewall rules accordingly.
The backup server daemon enables automatic continuous backup from source peers to a designated backup server.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MACHINE A (Source Peer) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββββββ β
β β Watch Folder β 1. User adds files β
β β ~/Documents/ ββββββββββββββββββ β
β ββββββββββββββββββββ β β
β β βΌ β
β β 2. File watcher ββββββββββββββββββ β
β β detects changes β Sync Service β β
β βββββββββββββββββββββββΊβ (Desktop App) β β
β ββββββββββ¬ββββββββ β
β β 3. Upload files β
β β (POST /data) β
β βΌ β
β ββββββββββββββββββ β
β β archivist-node β β
β β (Port 8080) β β
β ββββββββββ¬ββββββββ β
β β β
β β 4. Store files as CIDs β
β β file1.txt β zdj7W... β
β β file2.pdf β zDvZR... β
β β β
β ββββββββββββββββββββββββββββββββ β β
β β After 10 file changes: ββββββββββ 5. Threshold reached β
β β β β
β β Generate manifest file: β β
β β .archivist-manifest-{id}.jsonβ β
β β β β
β β { β β
β β "source_peer_id": "16Uiu..β β
β β "sequence_number": 1, β β
β β "files": [ β β
β β {"path": "file1.txt", β β
β β "cid": "zdj7W..."}, β β
β β {"path": "file2.pdf", β β
β β "cid": "zDvZR..."} β β
β β ] β β
β β } β β
β ββββββββββββββββ¬ββββββββββββββββ β
β β β
β β 6. Upload manifest β
β β (POST /data) β
β βΌ β
β ββββββββββββββββββ β
β β archivist-node β β
β β Manifest CID: β β
β β zDvZRwzm... β β
β ββββββββββ¬ββββββββ β
β β β
β β 7. Create storage request β
β β for backup peer β
β β β
βββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β 8. P2P Network
β (libp2p encrypted)
β
βββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MACHINE B (Backup Server) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββββββββββββββββββββββββββββ β
β β Backup Daemon (Background) β β
β β ββββββββββββββββββββββββββββββ β β
β β β Every 30 seconds: β β 9. Poll for manifests β
β β β GET /data βββββΌββββββββββββββ β
β β β Filter: *.manifest*.json β β β β
β β ββββββββββββββββββββββββββββββ β β β
β ββββββββββββββββββ¬ββββββββββββββββββββ β β
β β βΌ β
β β 10. Manifest βββββββββββββββββββββββββ β
β β discovered β archivist-node β β
β β β (Port 8080) β β
β β β β β
β β β Files stored: β β
β β β β’ manifest.json β β
β β β β’ file1.txt (zdj7W) β β
β β β β’ file2.pdf (zDvZR) β β
β β βββββββββββββββββββββββββ β
β β β
β β 11. Parse manifest β
β β Extract CID list β
β β β
β βΌ β
β ββββββββββββββββββββββββββββββββββ β
β β Download missing files β 12. For each CID: β
β β (3 concurrent downloads) β POST /data/{cid}/network β
β β β β
β β zdj7W... ββββββββββ 80% β (Download from network β
β β zDvZR... ββββββββββ 100% β via P2P from Machine A) β
β β zDpuA... ββββββββββ 10% β β
β ββββββββββββββββββ¬ββββββββββββββββ β
β β β
β β 13. Update state β
β βΌ β
β ββββββββββββββββββββββββββββββββββ β
β β backup-daemon-state.json β β
β β β β
β β { β β
β β "processed_manifests": { β β
β β "zDvZRwzm...": { β β
β β "source_peer_id": "...", β β
β β "sequence_number": 1, β β
β β "file_count": 15, β β
β β "total_size_bytes": ... β β
β β } β β
β β }, β β
β β "stats": { β β
β β "total_manifests": 1, β β
β β "total_files": 15, β β
β β "total_bytes": ... β β
β β } β β
β β } β β
β ββββββββββββββββββββββββββββββββββ β
β β
β ββββββββββββββββββββββββββββββββββ β
β β Backup Server Dashboard β 14. User views status β
β β (http://localhost:1420) β β
β β β β
β β Manifests Processed: 1 β β
β β Files Downloaded: 15 β β
β β Total Size: 2.4 MB β β
β β β β
β β Processed Manifests β β
β β Source: 16Uiu2HAm... (Seq #1) β β
β β Files: 15 | Size: 2.4 MB β β
β ββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Machine A (Source Peer):
- User adds files to watched folder
- File watcher detects changes (create/modify/delete)
- Sync service uploads files to local archivist-node via POST
/data - Node stores files and returns CIDs (content identifiers)
- After 10 file changes (configurable threshold), manifest is generated
- Manifest file created:
.archivist-manifest-{peer_id}.jsoncontaining:- Source peer ID
- Sequence number (increments with each update)
- List of all files with their CIDs
- Deleted files (tombstones for cleanup)
- Manifest uploaded to local node, gets its own CID
- Storage request created for backup peer (if configured)
P2P Network:
- Manifest propagates through libp2p network
- Peers exchange data using encrypted connections
- Content-addressed storage ensures data integrity
Machine B (Backup Server):
- Backup daemon polls
/dataendpoint every 30 seconds - Discovers new manifest files (filter:
*.manifest*.json) - Downloads and parses manifest to extract CID list
- For each CID in manifest:
- Check if already stored locally
- If missing: POST
/data/{cid}/networkto download from network - Downloads happen concurrently (3 at a time by default)
- Updates daemon state file with:
- Processed manifests
- Statistics (files downloaded, bytes, etc.)
- Failed downloads (for retry)
- Dashboard displays real-time backup status
# In config.toml on Machine A
[sync]
backup_enabled = true
backup_peer_address = "spr:CiUIAhIhAml6..." # Machine B's SPR
backup_manifest_enabled = true
backup_auto_notify = true
manifest_update_threshold = 10 # Generate manifest after N file changes# In config.toml on Machine B
[backup_server]
enabled = true
poll_interval_secs = 30 # Check for new manifests every 30s
max_concurrent_downloads = 3 # Download 3 files at once
max_retries = 3 # Retry failed downloads 3 times
auto_delete_tombstones = true # Process file deletions| Feature | Description |
|---|---|
| Event-Driven | Manifests generated automatically after threshold reached |
| Continuous Sync | New files trigger manifest updates without manual intervention |
| Deletion Tracking | Deleted files tracked in manifest for proper cleanup |
| Sequence Numbers | Detect gaps and ensure proper ordering |
| Retry Mechanism | Failed downloads automatically retried with backoff |
| Concurrent Downloads | Multiple files downloaded in parallel for speed |
| State Persistence | Daemon state saved to disk, survives restarts |
| Real-Time Dashboard | Monitor backup progress with auto-refreshing UI |
| n:1 Fan-In | Multiple source peers can backup to single server |
| Content Deduplication | Same file content = same CID = stored once |
For cross-network backup (Machine A β Internet β Machine B):
-
Machine A (Source) port forwarding:
- Forward external port 8070 (TCP) β Machine A's local IP:8070 (P2P)
- Forward external port 8085 (TCP) β Machine A's local IP:8085 (Manifest server)
-
Machine B (Backup Server) port forwarding:
- Forward external port 8070 (TCP) β Machine B's local IP:8070 (P2P)
- Forward external port 8086 (TCP) β Machine B's local IP:8086 (Backup trigger, optional)
-
Firewall rules:
- Machine A: Allow TCP 8070, 8085 and UDP 8090
- Machine B: Allow TCP 8070, 8086 and UDP 8090
-
Connection tip: If NAT traversal fails in one direction, try connecting from the other machine first. The machine with more permissive NAT/firewall should initiate the P2P connection.
| Issue | Solution |
|---|---|
| Port 8080 in use | Change API port in Settings β Advanced |
| Sidecar not found | Run pnpm download-sidecar |
| 0 addresses found | Check firewall allows ports 8090 (UDP) and 8070 (TCP) |
| Peer connects then disconnects | Check NAT timeout, try reconnecting with fresh SPR |
Node logs are written to:
- Linux:
~/.local/share/archivist/node.log - macOS:
~/Library/Application Support/archivist/node.log - Windows:
%APPDATA%\archivist\node.log
Use the built-in Logs page for real-time viewing with auto-refresh.
- GitHub Repository: https://github.com/durability-labs/archivist-desktop
- Sidecar Repository: https://github.com/durability-labs/archivist-node
- Developer Documentation: See CLAUDE.md for comprehensive technical docs
MIT
This software is provided for evaluation and testing purposes as part of the pilot program. See the warning at the top of this document regarding data safety.