Axel Meyer 2612d660dd
All checks were successful
CI / lint (push) Successful in 45s
CI / test (push) Successful in 32s
Bump CI Go to 1.24.13 to fix crypto/tls CVEs
GO-2026-4340, GO-2026-4337, GO-2025-4175 — all fixed in Go 1.24.13.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 01:17:37 +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 Tests golangci-lint govulncheck

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%