fuser: a Rust rewrite of the FUSE userspace library, not a set of bindings
Filesystem in Userspace (FUSE) for Rust
At a glance
- What is it?
- fuser is a Rust crate for writing filesystems that the kernel mounts through FUSE, replacing libfuse with a Rust implementation that keeps only the mount and unmount calls in C. It fits Rust developers who want the type system and the async runtime inside a filesystem, and it comes with a governance change that matters more than the API does.
- Who is it for?
- Adopt fuser if you are writing a filesystem in Rust and want to own the request handling loop in Rust rather than call into libfuse, and if you can run the Docker based test suites during development. Do not adopt it if you need macOS support you can rely on, since the README labels that platform untested, and do not plan to send pull requests, because the project has stopped accepting them.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 71 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A rewrite of libfuse rather than a wrapper around it
The distinction the README insists on is the first thing to understand about fuser. It is a Rust library crate for implementing FUSE filesystems in userspace, and the README says it does not just provide bindings, it is a rewrite of the original FUSE C library to fully take advantage of Rust's architecture. The project was originally forked from the `fuse` crate with the intention of continuing development, in particular adding features from ABIs after 7.19. So the crate occupies the layer where libfuse normally sits, and the origin fork is worth knowing because it means the API shape carries the conventions of the older crate rather than starting from scratch. The README also documents how the pieces fit together, and it is a three part arrangement: the kernel driver that registers as a filesystem and forwards operations through a communication channel, the userspace library that establishes and runs that communication, and the userspace implementation that actually processes the operations. The kernel driver comes from the FUSE project, the implementation is yours to write, and fuser is the replacement for the middle layer.
Only mount and umount still touch libfuse
The library is described as a replacement for libfuse between the kernel driver and your implementation, and the boundary is narrow. Except for a single setup call to mount and a final teardown call to umount, everything runs in Rust. On Linux those two calls are optional, and the README says they can be removed by building without the `libfuse` feature flag. That is the whole point of the rewrite: a filesystem in Rust where the request loop, the buffer handling and the attribute mapping are Rust code rather than a C library called through a foreign function interface. The Cargo.toml shows how little is left in C. The dependency list is `libc` and `nix` for the system interfaces, `zerocopy` for safe reinterpretation of byte buffers, `smallvec` for inline storage, `bitflags` and `num_enum` for flag and enum handling, `page_size` and `memchr` for buffer work, `parking_lot` for locking, and `log` for diagnostics. Serde is optional, pulled in by the `serializable` feature, and `async-trait` plus `tokio` are optional behind the `experimental` feature.
Feature flags decide whether libfuse is involved at all
The feature table in Cargo.toml is the practical configuration surface, and the default is empty, meaning a plain `cargo add fuser` pulls no optional machinery. `libfuse2` and `libfuse3` are the two ways to keep the C library, and each is just `libfuse` plus a version marker, so you pick the one matching the FUSE major version on the target system. `experimental` enables `async-trait` and `tokio` for filesystems that want an async request loop. `serializable` enables `serde` derive support. There is also a feature that disables the mount implementations entirely, where the manifest notes the code will compile but the filesystem will not be mounted, which is the escape hatch for platforms and environments where mounting is not possible, such as inside a container that lacks the right capabilities. The manifest declares edition 2024 and a minimum Rust version of 1.85, and the crate is published on crates.io as `fuser` with the reference documentation on docs.rs. The `examples/` directory shows the shape of the implementation, with `hello.rs`, `null.rs`, `passthrough.rs`, `passthrough_fork.rs`, `ioctl.rs`, `poll.rs`, `notify_inval_entry.rs`, `notify_inval_inode.rs`, and an `async_hello.rs`.
Installing the crate and the system packages it expects
The crate itself is one command, and the README also shows the manifest form:
cargo add fuser[dependencies]
fuser = "0.15"The system side needs more care, because FUSE itself has to be installed to build or run anything that depends on the crate, and `pkg-config` is needed to build. On a Debian based system the README gives `sudo apt-get install fuse3 libfuse3-dev` for the runtime, and `sudo apt-get install libfuse-dev pkg-config` for the headers used at build time; on CentOS the equivalents are `sudo yum install fuse` and `sudo yum install fuse-devel pkgconfig`. FreeBSD needs `pkg install fusefs-libs pkgconf`. macOS is the awkward one and the README labels it untested: it needs FUSE for macOS, version 10.9 or later, and on Apple Silicon you must enable support for third party kernel extensions. The Homebrew route is `brew install macfuse pkgconf`, and the Nix route installs `nixos.macfuse-stubs` and `nixos.pkg-config`, in which case you must point `PKG_CONFIG_PATH` at where macfuse is installed. To write a filesystem, you implement the trait `fuser::Filesystem`.
The test suite runs the real kernel filesystem tests in Docker
The repository layout shows a testing setup that goes well beyond unit tests. There are Dockerfiles for xfstests, for pjdfs with both libfuse2 and libfuse3 feature sets, and separate ones for libfuse2 and libfuse3 mount tests, alongside a `fuser-tests` workspace member. The Makefile target for xfstests builds an image and then runs it with a specific set of capabilities, and the comments explain why each one is needed: SYS_ADMIN to mount FUSE, SYS_PACCT for BSD process accounting, IPC_OWNER, and LINUX_IMMUTABLE for the chattr immutable and append tests, none of which are in Docker's default set, so those tests fail rather than skip. The seccomp profile is deliberately left on, with the reasoning that turning it off would let the io_uring tests run but would also unblock swapon, and swap is a global resource rather than a per container one. A Makefile `pre` target runs formatting checks, a licence check with `cargo deny check licenses`, and clippy across default, no default feature and all feature builds. That is a project that treats filesystem conformance as a first class concern, and it is also the reason the crate needs a Rust toolchain plus a container runtime to validate.
Development moved to coding agents and pull requests are closed
Two governance facts in the README deserve more attention than a features list would give them. The first is a note headed Use of AI: version 0.18.0 is the last version that was primarily developed without coding agents, and future releases will be developed primarily by a coding agent, on the stated grounds that this should lead to higher quality code and faster feature development, with changes receiving at least a cursory review from a human and a full review from a coding agent. The second is the contribution section, which says in bold that pull requests are no longer being accepted, and that you should file an issue or fork the project instead, with the remaining advice being to make the fork useful for the target audience and to keep the philosophy and Rust coding standards in mind. For an open source crate that has been a reference implementation for years, this is a meaningful change in who can propose work. The repository carries AGENTS.md and CLAUDE.md files, which is consistent with that direction, and the CHANGELOG.md is kept on the keepachangelog format.
Where fuser sits against libfuse and the crate it forked from
There are two comparisons worth making. The first is against libfuse itself, the C library that the FUSE project ships. The difference in approach is that libfuse is a C library with a C API, a session loop and a set of callbacks, while fuser reimplements that layer in Rust and hands the developer a Rust trait to implement. That buys type safety around the request and reply structures, Rust features in the implementation, and a feature flag that removes the C dependency entirely on Linux, at the cost of a smaller and less battle tested surface, since the README says most features of libfuse up to 3.10.3 are implemented and points you at the source for comments marked TODO or FIXME to see what is missing. The second comparison is with the `fuse` crate that fuser was forked from, and here fuser is the continuation rather than a competitor: same basic shape, more ABI coverage, and a different maintenance owner. The alternative for a team that values the classic API over the newer ABI coverage is to stay on the `fuse` crate, and the trade is coverage of newer kernel ABIs against a different API lineage.
Editorial conclusion
Adopt fuser if you are writing a filesystem in Rust and want to own the request handling loop in Rust rather than call into libfuse, and if you can run the Docker based test suites during development. Do not adopt it if you need macOS support you can rely on, since the README labels that platform untested, and do not plan to send pull requests, because the project has stopped accepting them. Before you commit, confirm that your system has the FUSE libraries and pkg-config in place, decide whether you need the libfuse2, libfuse3 or pure Rust path, and read the AI development note, since version 0.18.0 is the last release developed primarily without coding agents. The licence is MIT, with some example files under different terms, and the last push was on 2026-08-14.
Frequently asked questions
Does fuser require libfuse at runtime?
Only for the mount and umount calls, and on Linux even those are optional. The README says everything except the setup and teardown calls runs in Rust, and that the libfuse calls can be removed by building without the libfuse feature flag. The Cargo.toml offers libfuse2 and libfuse3 features to pick the FUSE major version you keep.
How do I add fuser to a Rust project?
Run `cargo add fuser`, or add `fuser = "0.15"` under `[dependencies]` in Cargo.toml. You then implement the trait `fuser::Filesystem`, with the `examples/` directory holding basic examples to start from.
Is macOS supported by fuser?
The README labels macOS as untested. It needs FUSE for macOS, version 10.9 or later, and on Apple Silicon you must enable support for third party kernel extensions. The project is developed and tested on Linux, and tested under FUSE for Linux and FUSE for FreeBSD.
Can I send a pull request to fuser?
No. The README states in bold that pull requests are no longer being accepted, and asks that you file an issue or fork the project instead, then make your fork useful for the target audience and update the changelog if the change matters to users.
What licence does fuser use?
The README says the project is licensed under the MIT Licence, except for those files in `examples/` that explicitly contain a different licence. The Cargo.toml also declares the licence as MIT.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/cberner-fuser)Was this useful?