Sorry for the long answer, but we speak about global perspectives to know where Syncthing stands, so it is important to consider several aspects.
Forks
Forking is not about extensibility. You fork when you want to do your own stuff, which can evolve as far away as you want from the basis. If you want someone who operates a “custom” Syncthing to still interact with a “standard” Syncthing, you need to ensure compatibility in some way. Forking does not care about that: it completely cuts the dependency. Compatibility then have to be maintained manually.
If you want to deal with forked variants of Syncthing in a compatible way, you are gonna have to deal with a mess. If you want to avoid that, then Syncthing should provide the acceptable boundaries, which is why extensibility should be supported by Syncthing itself.
Additional layer
We may think that people just have to implement an additional layer using Syncthing as a backend, but that means that all the features not related to the extension itself, but still provided by Syncthing, must be implemented too to make them available. Just to delegate them to Syncthing.
Moreover, depending on the kind of extension you provide, it might be hard to stack it with others: extension A does not know what extension B is providing, just exploiting the standard Syncthing stuff it supports.
People who are used to implement the decorator pattern probably know what I mean: you can stack them, but only if they remain within the adaptation of existing features. New features are lost by adding yet another layer aware only of the basic stuff.
Extensibility
Plugins are a way to go, although it is rather integrated and thus implies that the team spend some effort architecturing Syncthing in a pluggable way. But it ensures that whatever plugin we build has to be within the boundaries of what Syncthing accepts. Boundaries that can evolve at the rythm of Syncthing itself, so you keep control on that.
Another way to make it extensible is to establish a common interface/protocol that can be implemented by other apps to properly interact with Syncthing. But it means that any stuff that one needs to adapt must be exposed through this interface/protocols. Is the REST API adapted to this kind of use? Can we easily use it for instance to add the support of remaining space discussed here?
And there is probably other ways, each with its advantages and drawbacks. I don’t know what would be the most reasonable choice here. All I am pointing at is that some extensibility is required, and forking is a different matter.
From my point of view, Syncthing provides the entry point. And the whole point is to allow Syncthing to get custom, context-dependent adaptations, without having to impose the effort of each of them on the main team, and this is what extensibility is all about. There is of course the user interface to adapt, but also the processing, which makes it hard to just consider it as an additional layer.
Comparison with rsync
Rsync is not extensible. It is a standalone application that you can only run through what it supports directly. If you look at its man page, there is around 150 options that you can provide to customize its behaviour. All these options are maintained directly by rsync.
You can use rsync as a backend (behind an additional layer) to enrich its inputs and outputs, but you cannot adapt rsync itself to deal with contextual specificities unless it is already covered by the provided options.
For example:
-
-z/--compress
compresses the data.
-
--compress-level
provides the compression level to use
-
--skip-compress
allows to avoid spending time compressing files having a specific suffix
What if you want to change the compression algorithm? What if you want to skip the compression based on prefix instead of suffix? What if… You just cannot do it because rsync is not adaptable enough, either because of the lacking option or because of a lacking extensibility.
This is exactly what you risk by missing the extensibility aspect of Syncthing.
Conclusion
I totally agree that Syncthing should not deal with the many, context-specific features that everyone wants. I totally agree that it should focus on its job. But if you are not extensible, that focus becomes also the limit of Syncthing. Then people wanting more have to use something else. This “something else” might be based on Syncthing, but Syncthing remains the backend and can be replaced at any time because of its limits. However, if it is extensible, then Syncthing remains the main stuff, and plugins are secondary. The great stuff is related to Syncthing itself, not to some extra layer hiding Syncthing and dealing with its limits.
If you are OK with Syncthing to be a limited tool like rsync, that runs behind the door and can be replaced at any time when the limits are too annoying, then not caring about extensibility is reasonable.
If you want to be in the front, then adaptability becomes a requirement, otherwise you cannot deal with the fluctuating requirements of people (nobody remains within a restricted boundary for long). Then come the question: spend effort supporting all the stuff yourself, or make it extensible for other people to provide the additional stuff making Syncthing greater?