Read any Linux-supported filesystem from userspace — no root, no FUSE, no kernel modules.
Uses LKL (Linux Kernel Library) to run actual kernel filesystem code in a library. Supports raw disk images and QEMU-compatible formats (qcow2, vmdk, vdi) via linked QEMU block layer.
| Edition | Where | Engine |
|---|---|---|
| Web | https://anyfs.kosaka.moe: open a local image or an HTTP(S) URL; the image is read in the browser, not uploaded | wasm (LKL + QEMU block layer built with emscripten) in a Web Worker |
| Desktop: Linux x64, Windows x64, macOS (Apple silicon and Intel) | Electron app, see Desktop app | native addon (anyfs_native.node); the wasm engine is the fallback |
| CLI servers and tools | anyfs-ksmbd, anyfs-nfsd, anyfs-lspart, anyfs-fuse: tarballs from the linux, mingw64 and macos CI workflows, see docs/distribution.md and docs/macos.md |
native |
The desktop app is the web app's interface in Electron, with the kernel running natively in the app process instead of in wasm. It opens images by path (raw, qcow2, vmdk, vdi, vhd(x), dmg, ...) and HTTP(S) URLs, and reads them read-only.
An Ubuntu 26.10 cloud image (qcow2, development branch) opened in the Linux build: every GPT partition with its size, label, filesystem and partition type. The BIOS boot partition has no filesystem and cannot be opened.
The image's ext4 root filesystem, read by the Linux kernel's own ext4 driver running inside
the app (LKL). Symbolic links (bin, lib, sbin) carry a link icon.
Properties of /etc/hosts: mode, owner, inode, block usage and timestamps come from the
kernel's stat.
The screenshots show the Linux x64 package built by CI (sha-d11d371), captured with
Playwright (ts/tests/e2e/packaged/docs-screenshots.spec.ts).
Download. Tagged releases (vX.Y.Z) attach anyfs-electron-X.Y.Z-linux-x64.tar.gz,
anyfs-electron-X.Y.Z-windows-x64.zip, anyfs-electron-X.Y.Z-macos-arm64.zip,
anyfs-electron-X.Y.Z-macos-x64.zip and SHA256SUMS to
GitHub Releases; no desktop release has been
tagged yet. Every commit on main is also packaged by the
electron workflow: open a
run and download the anyfs-electron-sha-<commit>-<linux|windows|macos>-<x64|arm64>
artifact (GitHub sign-in required, kept 14 days). Each artifact holds the archive and its
.sha256.
Run.
# Linux
sha256sum -c anyfs-electron-<version>-linux-x64.tar.gz.sha256
tar -xzf anyfs-electron-<version>-linux-x64.tar.gz
./anyfs-electron-<version>-linux-x64/anyfs-demo# macOS (arm64 for Apple silicon, x64 for Intel)
shasum -a 256 -c anyfs-electron-<version>-macos-arm64.zip.sha256
ditto -x -k anyfs-electron-<version>-macos-arm64.zip .
xattr -dr com.apple.quarantine anyfs-electron-<version>-macos-arm64/anyfs-demo.app
open anyfs-electron-<version>-macos-arm64/anyfs-demo.appOn Windows, check the hash with Get-FileHash anyfs-electron-<version>-windows-x64.zip,
extract the zip and start anyfs-demo.exe. The packages are not code-signed: Windows
SmartScreen may show "Windows protected your PC" (choose More info, then Run anyway).
The macOS app is signed ad hoc only, not with a Developer ID and not notarized, so macOS
refuses to open a downloaded copy until the quarantine attribute is removed as above (or
System Settings → Privacy & Security → Open Anyway is used after the first attempt).
On Linux distributions that restrict unprivileged user namespaces (Ubuntu 24.04 and later),
Chromium's sandbox cannot start from an unpacked archive; run anyfs-demo --no-sandbox, or
make chrome-sandbox owned by root with mode 4755.
| OS | Arch | Requirement | Tested in CI on |
|---|---|---|---|
| Linux | x64 | glibc 2.25 or later and Chromium's usual desktop libraries (GTK 3, NSS, libgbm) | Ubuntu 26.04 |
| Windows | x64 | Windows 10 or later | Windows Server 2025 |
| macOS | arm64, x64 | macOS 12 or later (Electron 42's floor; the native libraries alone would go lower) | macOS 15 on Apple silicon and on Intel |
Native and wasm. The start screen says "Native bridge active" when the native addon is
loaded. If it cannot load, the app falls back to the wasm engine the web edition uses;
Settings → Disable native module switches to it on purpose. CI checks that every package
starts on the native backend. "Open system drive…" lists the computer's disks and
partitions with their filesystems, labels and mountpoints (the
drivelist-anyfs addon); opening a raw device
still needs the rights to read it (administrator, root or the disk group).
What CI runs on every package, on a runner of its OS (Ubuntu 26.04, Windows Server 2025, macOS 15 on Apple silicon and Intel):
- Image file: open a qcow2 test image, list its partitions, mount ext4 and hash a file.
- Drive enumeration: list the runner's own disks through "Open system drive…" (listing only; the runner's disks are never opened).
- Virtual block device I/O: the job attaches a test image as a read-only disk of its own
(Linux loop and nbd, a Windows VHDX, a macOS disk image) and reads it as a device: the
native backend, clicking it in "Open system drive…", and the CLI tools (
anyfs-lspart,anyfs-ksmbd,anyfs-nfsd), plus a run without access to the device that must be refused. The image is checked to be unchanged afterwards. Files served byanyfs-nfsdare read back on Linux and macOS only: Windows has no NFSv4 client. - Physical disks: real external drives are not tested.
Build and packaging details: ts/examples/electron-demo/README.md.
- Mount and read ext4, btrfs, xfs, f2fs, FAT, NTFS, etc. without root
- Multiple I/O backends:
- raw — direct
pread(), fastest (~1.3 GB/s) - gio — GLib GIO
GInputStream(~1.1 GB/s) - qemu — QEMU block layer for qcow2/vmdk/vdi/vhd (~0.8 GB/s)
- raw — direct
- Userspace SMB3 (
anyfs-ksmbd) and NFSv4 (anyfs-nfsd) servers — a host-side TCP splice routes traffic into the in-LKL servers without libslirp on the data path - FUSE frontend (
anyfs-fuse) on Linux; WinFSP frontend (anyfs-winfsp) on Windows - Minimal C API: 4 functions for kernel/disk management, then use LKL syscalls directly
#include "anyfs.h"
#include <lkl.h>
#include <lkl/linux/stat.h>
// 1. Start kernel
anyfs_kernel_init(NULL); // or pass AnyfsKernelOpts
// 2. Add disk (auto-selects backend, or specify ANYFS_BACKEND_QEMU etc.)
int disk_id = anyfs_disk_add("disk.qcow2", ANYFS_DISK_READONLY);
// 3. Mount partition 1 — anyfs_mount picks an LKL mount point under /lklmnt/
AnyfsMount m;
anyfs_mount(disk_id, 1, "ext4", LKL_MS_RDONLY, NULL, &m);
// 4. Use LKL syscalls — full Linux VFS at your disposal
char path[256];
snprintf(path, sizeof path, "%s/etc/passwd", m.mount_point);
long fd = lkl_sys_open(path, LKL_O_RDONLY, 0);
lkl_sys_read(fd, buf, sizeof(buf));
lkl_sys_close(fd);
struct lkl_stat st;
lkl_sys_lstat(path, &st);
struct lkl_dir *dir = lkl_opendir(m.mount_point, &err);
// ...
// 5. Cleanup
anyfs_umount(m.mount_point);
anyfs_disk_remove(disk_id);
anyfs_kernel_halt();- Linux (x86_64)
- Meson ≥ 0.60, Ninja
- Pre-built LKL (
liblkl.a) fromlinux/tools/lkl/ - Optional: static GLib/GIO for GIO backend
- Optional: static QEMU block libs for QEMU backend
# Minimal (raw backend only)
meson setup builddir -Dlkl_root=$HOME/linux/tools/lkl
# Full (raw + GIO + QEMU)
meson setup builddir --default-library=static \
-Dlkl_root=$HOME/linux/tools/lkl \
-Dglib_root=$HOME/glib -Denable_gio=true \
-Denable_qemu=true \
-Dqemu_root=$HOME/qemu \
-Dqemu_build=$HOME/qemu/build-anyfs2
ninja -C builddirReading ~150 MB of files from a 256 MB ext4 image:
| Backend | Raw image | qcow2 |
|---|---|---|
| raw (pread) | 1295 MB/s | — |
| gio | 1071 MB/s | — |
| qemu | 722 MB/s | 818 MB/s |
Run yourself: ./builddir/bench_backends <image> <fstype> [part]
anyfs-reader includes two userspace file servers that expose disk-image partitions over the network using LKL's in-tree ksmbd and nfsd subsystems. No root, no kernel modules; a host-side TCP splice (src/host_proxy/) routes client traffic into the in-LKL listener — libslirp is not on the data path.
| Server | Protocol | Host port (default) | Build option |
|---|---|---|---|
anyfs-ksmbd |
SMB3 (CIFS) | 4455 | -Denable_ksmbd=true |
anyfs-nfsd |
NFSv4 | 20049 | (same flag) |
# Build the servers
meson setup builddir-ksmbd -Dlkl_root=$HOME/linux/tools/lkl \
-Denable_ksmbd=true -Dksmbd_tools_root=$HOME/ksmbd-tools
ninja -C builddir-ksmbd anyfs-ksmbd anyfs-nfsd
# Discover partition paths first
./builddir-ksmbd/src/lspart/anyfs-lspart disk.img
# SMB3 server
./builddir-ksmbd/anyfs-ksmbd disk.img --share data=disk0/p1
smbclient //localhost/data -U guest%guest --port=4455
# NFSv4 server
./builddir-ksmbd/anyfs-nfsd -w disk.img --share data=disk0/p1
mount -t nfs4 localhost:/data /mnt -o port=20049,vers=4See docs/lkl-servers.md for kernel config, the --share DSL, NFSv4 implementation details, and pynfs results.
The ts/ workspace ships the same anyfs stack as a wasm bundle plus thin JS
wrappers, so disk images can be inspected entirely client-side:
| Package | Role |
|---|---|
@anyfs/core |
wasm kernel (LKL + QEMU block layer) + JS bindings; runs in a Web Worker |
@anyfs/react |
React 18/19 hooks (useDir, useFile) over @anyfs/core |
@anyfs/trees |
<AnyfsFileBrowser> — Chonky-based file UI |
@anyfs/native |
Node N-API addon, links the native libs instead of wasm (Linux, Windows, macOS) |
A live build of the browser demo (ts/examples/vite-demo) is hosted at
https://anyfs.kosaka.moe — drop a disk image onto the page or paste an
HTTP URL and the kernel boots in-browser. The desktop app
(ts/examples/electron-demo) wraps the same interface in Electron.
cd ts
pnpm install
pnpm -r --filter './packages/*' build
pnpm -F vite-demo dev # http://localhost:5173See docs/ts-packages.md for the full layout, build recipes, and the wasm-specific gotchas.
include/anyfs.h — Public API (4 functions + a few mount helpers)
include/anyfs_disk.h — Multi-partition session layer
src/core/anyfs.c — Kernel init + disk management
src/core/anyfs_disk.c — Partition session + container recursion
src/core/raw_blk_backend.c — pread-based block backend
src/core/gio_blk_backend.c — GIO synchronous backend
src/core/qemu_blk_backend.c — QEMU block backend bridge
src/host_proxy/ — Host-side TCP splice (used by ksmbd/nfsd)
src/ksmbd/lkl_ksmbd.c — SMB3 server (LKL + ksmbd-tools)
src/nfsd/lkl_nfsd.c — NFSv4 server (LKL nfsd + mini mountd)
src/fuse/anyfs_fuse.c — FUSE3 frontend (Linux) and WinFSP frontend (Windows)
src/lspart/anyfs_lspart.c — Partition lister
src/bench/ — Benchmark / diagnostic utilities
tests/ — Regression tests
docs/ — Architecture, distribution, server docs
scripts/ — gen_lkl_config / build_lkl / build_qemu / build_anyfs / package_*
See docs/README.md for the full documentation index.
GPL-2.0 — see LICENSE.


