Wusel: Nextcloud, woven into your Linux desktop — and why we built it
At ITBH we work with files all day: documents, drawings, exports, the whole mess of a real project. Most of them live in our self-hosted Nextcloud. And for years, working with them on Linux meant one of two unappealing choices: keep a browser tab open on the Nextcloud web UI, or let the official desktop client mirror gigabytes onto every laptop whether we need them or not.
Neither felt right. So we built a third option — Wusel, a virtual filesystem for Nextcloud, written in Rust — and we've decided to open it.
The thing that never sat right with me
Let me be upfront and fair: the official Nextcloud desktop client is a solid piece of software, and the team behind it has good reasons for the way it's built. It maintains a single Qt/C++ codebase across Windows, macOS and Linux. As an engineering decision, that's perfectly defensible — one codebase is cheaper to maintain than three.
But it has a consequence, and it's the one I could never quite make peace with: virtual files — online-only placeholders that download on access — work on Windows and macOS, but not on Linux. Windows uses the Cloud Files API (also known as the Cloud Filter API), macOS uses File Provider, and Linux… gets full local sync. The shared codebase needs a mechanism that exists on all three platforms, and there isn't one, so Linux is left out. (You can find plenty of community threads asking for it.)
And that's the part I find genuinely puzzling. Because on Linux, the mechanism for exactly this has been sitting right there for two decades: FUSE. A filesystem in userspace, where your code answers every open and read. If you want files that look present but are only fetched when touched, FUSE gives you that almost by definition — the kernel simply doesn't have the bytes until a read asks for them. On Linux, virtual files aren't the hard case. They're the obvious case. Skipping FUSE to keep one shared codebase is understandable — but from where I sit, it leaves the best part of the Linux desktop on the table.
And no, raw WebDAV is not the answer either
The usual retort is: "just mount the WebDAV endpoint." We tried. It's slow in a way that's hard to overstate — every directory listing, every stat, every tab-completion becomes a network round-trip. The bottleneck was never the bandwidth of a single download; it's the latency of all that metadata chatter. Working like that, day in and day out, is beneath the dignity of a modern desktop.
The fix isn't "more WebDAV." It's a proper cache-first virtual filesystem: answer metadata instantly from local state, stream file content live on the first read, cache it, and keep it fresh via the server's push channel. That's what Wusel does.
Not a tray, and not a browser tab
Two conventions in this space rubbed us the wrong way, for different reasons.
Not a tray icon. When a sync tool wants to show status — is this file synced, is it uploading, is there a conflict — the reflex is to put a little icon in the system tray and grow it into an application of its own. Modern file managers already have the language for this: emblems and overlay icons on the file itself, a sidebar entry for the cloud provider, a right-click menu for per-file actions. That's where file status belongs — right on the file. A tray icon that slowly becomes half a desktop environment in a pop-up menu is the wrong answer.
Not a browser tab, either. Nextcloud's web UI is a rich mini-desktop of its own — files, chat, calendar, activity, all in a single page. That's genuinely useful for a lot of workflows, and we're not against it. But for the everyday rhythm of opening, editing and saving files, a browser tab isn't the right shape. And on Linux today, the official desktop client leaves you with a stark choice: mirror everything locally — often gigabytes, sometimes terabytes — or fall back to experimental workarounds. That's the choice we couldn't accept.
Wusel is opinionated: it uses what the desktop already gives you, instead of re-modelling it. Your file manager already has a sidebar, per-file emblems and a context menu. Your desktop already has search, notifications and a keyring. Your init system already knows how to run a background service. So that's where Wusel lives — not in a tray, not in a browser, and not in a second UI you have to learn. A file in your cloud should behave like any other file on your machine.
What already works
It's early — this is version 0.1.0 — but Wusel already does a satisfying amount, and we run it on our own machines every day.
One thing worth clarifying up front: the filesystem itself is neither distribution- nor desktop-specific. FUSE is a kernel interface every mainstream Linux ships, and Wusel mounts your Nextcloud at ~/Wusel on Fedora, Ubuntu, Debian, openSUSE, Arch, Alpine — whatever you happen to run. What is currently GNOME-first is the desktop-integration layer on top: the file-manager sidebar entry, the emblems, the context-menu actions, the Shell search. That layer exists because we run Fedora + GNOME internally, so we built for the desktop we use every day. KDE support is on the roadmap; for Cinnamon, XFCE, LXDE and others — and just as much for distributions beyond Fedora — we very much welcome help with builds and testing.
Concretely, today you get:
- Your Nextcloud as a folder at
~/Wusel. Files are online-only by default and stream from the server the moment you open them. No full mirror. Behaviour, mount path and cache limits are configurable. - Multiple Nextcloud accounts side by side — useful when you work with several clients, each running their own Nextcloud.
- Native GNOME/Nautilus integration: a Wusel (Nextcloud) entry in the sidebar, a per-file status emblem (online-only, cached, pinned, pending upload), and a right-click Make Available Offline / Free Up Space toggle.
- Search from the desktop: start typing in the Activities overview and your Nextcloud files show up, opening straight from
~/Wusel. - Pinning to keep chosen files or folders offline, write-back uploads with conflict handling, and live change detection over
notify_push. - Desktop notifications in your own language, credentials in the OS keyring by default, running as a systemd user service, and installable from a Fedora RPM.
Not everything is done — native macOS and Windows frontends are far-future experiments, and there's plenty of polish ahead. But the core idea is real and usable today.
How it compares on the Linux desktop
To be fair, the official client is broader, cross-platform and more mature. This is about the Linux desktop experience specifically — where the on-demand, native-integration story is Wusel's whole reason to exist.
| Feature (Linux desktop) | Wusel | Official Nextcloud client |
|---|---|---|
| Online-only files, no full local copy | ✅ | ❌ ¹ |
| Content fetched on first open (on-demand) | ✅ | ❌ |
| Local cache for instant re-opening | ✅ ² | ✅ ² |
| Pin files/folders "always offline" | ✅ | ✅ ³ |
| Fast browsing — no per-listing round-trip | ✅ | ✅ |
| Status emblems in the file manager | ✅ ⁴ | ✅ ⁴ |
| Cloud-provider sidebar entry (libcloudproviders) | ✅ | ❌ |
| Pin/unpin from the file-manager context menu | ✅ | ❌ |
| Search your cloud from the desktop (GNOME Shell) | ✅ | ❌ |
| Live updates on server change (notify_push) | ✅ | ✅ |
| Localized desktop notifications | ✅ | ✅ |
| Write-back with conflict handling | ✅ | ✅ |
| Credentials in the OS keyring | ✅ | ✅ |
| Runs headless — no tray, no browser | ✅ | ❌ ⁵ |
| Graphical configuration + share-link management | ❌ ⁶ | ✅ |
| Native macOS & Windows | ❌ ⁷ | ✅ |
| Distribution on Linux | Distro-native (Fedora RPM today) ⁸ | AppImage with in-app updater |
| License | Apache-2.0 | GPL |
- Virtual files work in the official client on Windows (Cloud Files API, also known as Cloud Filter API) and macOS (File Provider), but not on Linux — only full or selective sync.
- Wusel caches on demand (bounded, evictable); the official client keeps a full local copy of everything it syncs.
- Official client via selective sync (folder granularity).
- Both show emblems — the official client's reflect sync state, Wusel's reflect VFS state (online-only / cached / pinned / pending upload).
- The official client is driven by a system-tray GUI.
- Wusel is CLI-driven today; a small configuration UI (not a tray) is planned.
- Native macOS (File Provider) and Windows (Cloud Filter) frontends are far-future experiments.
- Installation requires root today. A rootless path is on the roadmap, but wasn't a priority for us internally — in enterprise environments someone else usually decides what goes on a machine, and on a private laptop you tend to have the rights anyway. See On distribution below.
On distribution — using what the distro gives us
The same principle that shaped the desktop story shaped how we ship. We prefer the tools a distribution already has, wherever they make sense.
Wusel ships today as a Fedora RPM. If you're on Fedora, you install, upgrade and remove it the way you handle everything else on the system — through dnf. No pop-up nagging you to update, no bespoke installer, no self-owned auto-update daemon quietly running in the background. That's not just an aesthetic preference; it's a matter of trust boundaries. Whatever mechanism your OS uses to review and roll out updates should be the one that reviews and rolls out ours.
We've deliberately avoided AppImage. It has a real strength — a single artifact that runs across distributions — and we understand why projects choose it. But it comes with a cost: the app has to ship its own updater, and every AppImage-shipped tool ends up as one more thing on your system that decides for itself when and what to fetch. That's not a model we want to add to.
Our preference for cross-distribution shipping would be Flatpak — sandboxed, updated through the distribution channel the user already trusts, and increasingly first-class on modern desktops. But Flatpak and FUSE are not a comfortable pairing today: mounting a userspace filesystem that has to be visible to the rest of the system doesn't compose neatly with the sandbox model. That's not a criticism of either — they solve different problems — it's just a constraint we ran into. If that story improves, we'll revisit.
There's one honest tension we haven't resolved. If we want Wusel to be installable without root — a reasonable request — then some form of user-space update path may be unavoidable, which brings us right back to something that looks awkwardly like an in-app updater. We'd rather not go there. But if we do, we'll be clear about it and it will be the last resort.
For now: Fedora users get an RPM, we're happy to help with packaging for other distributions — and just as happy to accept help going the other way — and we're keeping an eye on how Flatpak evolves.
A Rust project you're invited to read
Wusel is also, deliberately, a way to dive into Rust. The engine (wusel-core) is platform-independent and readable; the FUSE frontend is a thin adapter; the GNOME integration is its own layer. We kept the comments a little fuller and more explanatory than you'd write for a codebase of nothing but experts — the why and the Rust concept in play, not just the what. If you've been looking for a real-world Rust project to read or contribute to — protocol handling, an async↔sync bridge, a cache-first filesystem — this is a friendly one to start with.
Built with AI — and reviewed by humans
One more thing worth saying out loud, because the industry conversation on this is somewhere between shrill and reflexive: Wusel was built with heavy assistance from Claude Code, and we're not shy about it.
We think blanket bans on AI-assisted code miss the point. The interesting question was never "should code be written with AI." It's the same question that has always mattered: does a human understand what's shipping, has it been tested, and will a human own it when it breaks. On all three counts, Wusel qualifies.
What we reject is the other extreme — accepting whatever an assistant emits, no review, no test, no design pushback, and stitching it into a system as if the exercise were done. That's not engineering; that's noise dressed as code. Every commit in Wusel has a human behind it, an intent behind it, and enough test coverage behind it to be believed.
Used well, AI-assisted coding lets a small team ship more thoughtful, more polished software than it otherwise could — and frees human effort for the parts that actually need judgement: the architecture decisions, the ergonomic choices, the honest reflection about who your users are. That's how we used it here.
Why we opened it
We built Wusel because we wanted it for ourselves, and we use it internally every day. We're opening it under Apache-2.0 because we think other Linux desktop users want the same thing: their Nextcloud, native in their desktop, without a browser tab and without a full local copy of everything.
A closing word of respect: none of this is a swipe at Nextcloud. We rely on it, we're grateful for it, and "for Nextcloud" here is a compatibility statement, not a claim of affiliation. We'd simply love to see on-demand, virtual files become first-class on Linux — Wusel is our answer.
Try it: the Wusel page · https://github.com/itbh-at/wusel · docs at https://itbh-at.github.io/wusel/ · grab the RPM from the Releases page.
Comments