asopi tech
asopi techIndie Developer

Asopitech With · File sync

Syncthing with Alopex Chirps

Syncthing is an open source file sync tool that keeps files in step across two or more devices. What if we rebuilt it by applying Alopex Chirps?

Updated: Oct 13, 2026

What the service does

Syncthing is an open source tool that synchronizes files between two or more devices. Devices name each other by a device ID derived from their keys, and connect only when both sides have added each other. The data is the set of devices and the files in shared folders.

How the communication is built

  • Linking devices: each device holds a certificate, with the certificates of trusted peers configured. Chirps accepts only the certificates you configured as trusted, so registered devices connect to each other.
  • Membership: gossip tells whether each sync peer is alive, suspect or dead right now. When a peer comes back, the changes that piled up are sent to it.
  • File sync: for each file, choose push, pull or bidirectional sync. When both sides changed, decide whether the newer copy, the source or the target wins.

Watching folders and deciding which files to sync are the application’s code.

Deployment

Chirps is embedded in the app on each device, and the seed list holds devices that are always on. Devices connect directly over QUIC.

Why Alopex Chirps fits

File sync comes down to three things: connecting only with registered peers, knowing whether peers are alive, and syncing reliably. Chirps has all three together, mutual TLS authentication, gossip membership and sync that checks hashes.

See it in code

A hybrid logical clock decides which of two devices’ changes is newer, consistently. Just the core (Rust).

use alopex_chirps_gossip_swim::hlc::{Clock, LocalHlc};
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
use std::time::Duration;

// 説明用の手動クロック(実際はシステム時計)
struct ManualClock(AtomicU64);
impl Clock for ManualClock {
    fn now_millis(&self) -> u64 {
        self.0.load(Ordering::SeqCst)
    }
}

fn main() {
    let skew = Duration::from_secs(1);
    // 同期する 2 つの機器 A / B。時計が多少ずれていてもよい
    let mut a = LocalHlc::with_clock(skew, Arc::new(ManualClock(AtomicU64::new(100))));
    let mut b = LocalHlc::with_clock(skew, Arc::new(ManualClock(AtomicU64::new(90))));

    // A 側でファイルを変更するたびに時計を進める
    let change1 = a.tick();
    let change2 = a.tick();
    println!("A: change1={change1:?} change2={change2:?}");

    // A の変更を B が受け取ると、B の時計は A を追い越す
    let seen = b.receive(change2).expect("receive");
    println!("B receives A: {seen:?}");

    // その後 B 側で起きた変更は、A の変更より新しいと一貫して判断できる
    let b_change = b.tick();
    println!("B next: {b_change:?}");
    assert!(b_change > change2);
    println!("OK: 両機器が、どちらの変更が新しいかを一貫して判断できる");
}

Even with clock skew, you can consistently decide which change is newer and resolve two-sided edits. Mutual-TLS auth and gossip membership are handled by Chirps, as the prose describes.

Build a sync app with Alopex Chirps, syncing files in both directions between registered devices only. Start from the quickstart on GitHub.