Axel Meyer 99eeffcbe4
Some checks failed
Release / build (push) Failing after 2m53s
Detect missing Syncthing, rewrite README with architecture diagram
Add Syncthing installation detection (PATH + config file check) to both
the tray app and setup installer. When missing, the tray shows an
"Install Syncthing..." menu item and the setup opens the download page.

Rewrite README with Mermaid topology graph, per-binary dependency tables,
project layout, API endpoint reference, and shields.io badges.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 00:08:34 +01:00
2026-03-03 21:16:28 +01:00
2026-03-03 21:16:28 +01:00
2026-03-03 21:16:28 +01:00

SyncWarden icon
SyncWarden

Lightweight system tray wrapper for Syncthing. Cross-platform, native-feeling, ~10 MB.

Go 1.24+ Platform: Windows | Linux | macOS MIT License
Latest Release CI

Tray icon states: idle, syncing, paused, error, disconnected

Features

  • Tray icon with 5 states: idle (green), syncing (blue), paused (gray), error (red), disconnected (dark gray)
  • Real-time monitoring via Syncthing event API (long-polling) + periodic health checks
  • Transfer rates in tooltip and menu
  • Context menu: folder list, recent files, conflict counter, pause/resume, rescan, restart
  • Embedded admin panel using the system browser engine (Edge WebView2 / WebKit / WebKit2GTK)
  • OS notifications for sync complete, device connect/disconnect, new device requests, conflicts
  • Settings toggleable via menu checkboxes (persisted to JSON config)
  • Auto-start Syncthing with crash recovery and supervised restart
  • API key auto-discovery from Syncthing's config.xml
  • Syncthing detection — prompts with download link if Syncthing is not installed

How It Works

SyncWarden sits in the system tray and communicates with a local Syncthing instance via its REST API. It never touches your files directly — all sync operations are handled by Syncthing itself.

graph TB
    subgraph OS["Operating System"]
        tray["System Tray Icon"]
        notif["OS Notifications"]
        browser["Default Browser"]
        fm["File Manager"]
    end

    subgraph SW["SyncWarden"]
        subgraph tray_bin["syncwarden (tray binary)"]
            app["Tray App"]
            menu["Context Menu"]
            mon["Monitor"]
            evl["Event Listener<br/><small>long-poll /rest/events</small>"]
            poll["Health Poller<br/><small>every 3s</small>"]
            proc["Process Manager<br/><small>auto-start + restart</small>"]
            cfg["Config<br/><small>JSON file</small>"]
        end

        panel_bin["syncwarden-panel<br/><small>(embedded browser)</small>"]
        setup_bin["syncwarden-setup<br/><small>(installer)</small>"]
    end

    subgraph ST["Syncthing (localhost:8384)"]
        api["REST API"]
        webui["Web UI"]
        sync["Sync Engine"]
    end

    remote["Remote Devices"]

    %% Tray app connections
    app --> tray
    app --> notif
    app --> menu
    menu -- "Open folder" --> fm
    menu -- "Open Admin Panel" --> panel_bin
    panel_bin -- "renders" --> webui
    menu -- "Install Syncthing..." --> browser

    %% Monitor connections
    app --> mon
    mon --> evl
    mon --> poll
    evl -- "events" --> api
    poll -- "health + connections" --> api
    menu -- "pause / rescan / restart" --> api

    %% Process management
    app --> proc
    proc -- "start / stop / supervise" --> ST

    %% Config
    app --> cfg

    %% Syncthing
    sync <--> remote

    %% Styling
    classDef swbin fill:#2d5a27,stroke:#4a8,color:#fff
    classDef stbox fill:#1a4a6a,stroke:#3a8abf,color:#fff
    classDef osbox fill:#555,stroke:#888,color:#fff

    class app,menu,mon,evl,poll,proc,cfg swbin
    class panel_bin,setup_bin swbin
    class api,webui,sync stbox
    class tray,notif,browser,fm osbox

Data Flow

  1. Event Listener long-polls GET /rest/events — receives real-time sync events (file changes, device connections, folder state changes)
  2. Health Poller checks /rest/noauth/health and /rest/system/connections every 3 seconds — detects connection loss and calculates transfer rates
  3. Monitor aggregates both streams into a single status snapshot (icon state, device count, rates, recent files, conflicts)
  4. Tray App renders the status as an icon + tooltip + menu updates, and dispatches OS notifications for configured events

Architecture

SyncWarden ships as three separate binaries to avoid main-thread conflicts between systray and webview:

Binary Purpose CGO
syncwarden Tray icon, menu, monitoring, notifications, process management No
syncwarden-panel Embedded browser showing Syncthing admin UI Yes
syncwarden-setup Cross-platform installer / uninstaller No

Project Layout

cmd/
  syncwarden/       Entry point for tray binary
  panel/            Entry point for embedded browser panel
  setup/            Cross-platform installer
  icongen/          Icon generation utility (dev tool)
internal/
  config/           Config persistence + platform-specific paths
  icons/            Pre-rendered tray icons (5 states, PNG + ICO)
  monitor/          State aggregation: folders, speed, recent files, conflicts
  notify/           OS notification wrapper
  syncthing/        REST API client, event listener, process manager, detection
  tray/             Tray UI: menu, tooltip, panel launcher

Installation

From release

Download the latest release for your platform from Releases and run syncwarden-setup.

If Syncthing is not installed, the setup will open the download page for you.

From source

Requires Go 1.24+ and CGO (MinGW-w64 on Windows) for the panel binary.

# Tray binary (pure Go, no CGO needed)
go build -o syncwarden ./cmd/syncwarden

# Panel binary (requires CGO + C++ compiler)
CGO_ENABLED=1 go build -o syncwarden-panel ./cmd/panel

# Setup
go build -o syncwarden-setup ./cmd/setup

Configuration

Config file location:

  • Windows: %LOCALAPPDATA%\syncwarden\config.json
  • Linux: ~/.config/syncwarden/config.json
  • macOS: ~/Library/Application Support/syncwarden/config.json

The API key is auto-discovered from Syncthing's config.xml on first run. All settings are configurable via the tray menu.

Dependencies

Tray binary (syncwarden)

Dependency Purpose
energye/systray System tray integration (icon, menu, click events)
fogleman/gg 2D graphics for icon rendering
gen2brain/beeep Cross-platform OS notifications

Panel binary (syncwarden-panel)

Dependency Purpose
webview/webview_go Embedded browser (Edge WebView2 / WebKit / WebKit2GTK)

Setup binary (syncwarden-setup)

No external dependencies — uses only the Go standard library and internal/config for path resolution.

Build-time only

Tool Purpose
goreleaser/nfpm .deb package generation (CI only)

Syncthing REST API Usage

SyncWarden communicates with Syncthing via its local REST API. All requests go to localhost:8384 (configurable) and are authenticated with the X-API-Key header.

Endpoint Purpose
GET /rest/noauth/health Connection health check (no auth)
GET /rest/system/connections Device status + byte counters for rate calculation
GET /rest/config Folder and device configuration
GET /rest/db/status Per-folder sync state
GET /rest/events Long-poll event stream (30s timeout)
POST /rest/system/pause Pause all syncing
POST /rest/system/resume Resume all syncing
POST /rest/db/scan Trigger folder rescan
POST /rest/system/restart Restart Syncthing

License

MIT

Description
Lightweight system tray wrapper for Syncthing
Readme MIT 994 KiB
v0.3.0 Latest
2026-03-03 23:57:39 +00:00
Languages
Go 99.8%
Shell 0.2%