Potential new Syncthing cross-platform client ui

Hello all!

I was looking for a non-cloud multi-device file sharing solution, and Syncthing appears to be the solution. Judging from this Hacker News thread, it seems like the common complaints are about ease-of-use: Syncthing – a continuous file synchronization program | Hacker News (ycombinator.com)

I am thinking of making a thick wrapper for Syncthing to configure it to be more like OneDrive, Dropbox, etc. just to be more accessible to the average person.

First of all, would that be useful to the community?

And secondly, it looks like the current wrappers interface with the Syncthing rest api. Would it be possible to treat Syncthing as a library and interface directly?

1 Like

Check GitHub - Martchus/syncthingtray: Tray application and Dolphin/Plasma integration for Syncthing

It’s quite an amazing project by a person that clearly has “a bigger bottle” than syncthing folks have.

We know by heart that cross platform is hard, and cross platform ui is 100x harder than just reading some files off the disk.


@AudriusButkevicius Thanks for mentioning my project and the kind words :grinning:

That is true and also counts for Syncthing Tray to some degree. Syncthing Tray uses the REST-API to monitor and control Syncthing. However, it also allows to start Syncthing as part of the GUI process as it can indeed build and link against Syncthing as a library. The communication is then nevertheless still done via the REST-API because crossing the C++/Go library boundaries is tedious enough for handling startup/termination and Syncthing itself also doesn’t appear to provide a stable public API (not even for other Go applications). The REST-API on the other hand is quite stable and reliable.

Note that on GNU/Linux it is also quite desirable to have Syncthing as an external process as you might not even always have a graphical session around and can install and update Syncthing itself quite conveniently via your package manager.

By the way, that’s Syncthing Tray’s documentation regarding this: GitHub - Martchus/syncthingtray: Tray application and Dolphin/Plasma integration for Syncthing

I think Syncthing Tray makes it somewhat accessible to the average person although a setup wizard is still on the TODO list.

Additionally, one currently needs to build binaries for MacOS manually because there are no (actively maintained) repositories/builds.

1 Like

A setup wizard or a very simple install guide for syncthingtray would be awesome. I’d really like to recommend it as the de-facto standard wrapper for linux/bsds (while also usable cross-platform, just that I guess the targeted windows/mac wrappers are still a bit better there). However while it’s fairly straightforward to set up if you know your way around a computer, I don’t think it’s simple enough yet for the average user and “mass-adoption”.

I must admit I completely disregarded this aspect so far. We indeed use the versioning exclusively to refer to config/api/application compatibility, not for the go APIs. We probably should add that to the reasons for a minor version bump (see Versions & Releases — Syncthing documentation). I know technically it would be a major bump in normal go conventions, but that would require different versions for the code and the actual application. Which basically means separating library and application code - I don’t think there’s any plans to do that (I know you didn’t ask, just felt like mentioning it in this context).

1 Like

Interesting that you mention it, I wasn’t aware of that definition.

You should then also clarify what APIs are relevant to that versioning because you certainly don’t want all code in the repository to be considered here. (In traditional C/C++ projects the public API is usually defined by the set of headers that is installed when invoking the project’s install target. Not sure how that’s defined in Go projects.)

Actually very understandable considering Syncthing’s own UI is only using the REST-API as well and a library interface for more than just starting/stopping is not that important.


Yeah I was thinking of defining a set of packages (which corresponds to directories in go) for which we give that guarantee. Probably (a subset of) ./cmd/... and ./lib/syncthing. Would that even be useful to you? However that’s only a thought prompted by this discussion, not something I planned on acting on anyway. You’re afaik the only consumer of those - would this even matter/be useful to you?

1 Like

I’m not sure. Currently I’m using these modules: Add basic C bindings to start and stop Syncthing and invoke its CLI · Martchus/syncthing@ced426e · GitHub However, currently I’m mainly starting/stopping Syncthing and everything else is still done via the REST-API. I’m also not sure how much sense it’ll make to change that and how much effort I’m willing to spend (considering that there’s likely no real user visible improvement).

As you can see in the diff, I also had to refactor code in cmd/syncthing/cli/main.go to expose Syncthing’s CLI. (I thought when I have Syncthing built into Syncthing Tray it makes also sense if Syncthing Tray’s executable provides Syncthing’s CLI as a sub-command.) Maybe it would actually make sense to upstream that diff. It shouldn’t harm Syncthing itself and I won’t potentially have less conflicts to worry about when rebasing.

By the way, last time I wanted to consume Syncthing as a Go module I ran into the problem that Go’s build system doesn’t handle asset creation correctly.

Of course.

As mentioned before I’m not sure whether shifting more from using the REST-API to direct function calls will be very useful. In any case I still need to support the REST-API for users using an external Syncthing instance. For the code I’m interfacing with at this point I always relied on the Go compiler telling me that something is wrong after rebasing against the latest Syncthing release. I also have some basic unit/integration tests. So versioning to know about problematic changes before seems unnecessary (considering I will find out about them anyways).

1 Like

Nothing will change about that. All that can be controlled through the library at this time is a big bunch of startup options. One thing I had in mind at some point was allowing to pass a logging facility in, not planned though at the moment.
This really only is about guaranteeing some stability/notice if that start/stop API changes.

Upstreaming that seems reasonable indeed.

1 Like