FUSE Composition Layer
The FUSE composition layer provides a unified filesystem view of your repository and its dependencies at a fixed mount location. This enables:
- Predictable paths for remote cache compatibility
- Transparent editing of external dependencies
- Automatic consistency management during updates
Quick Start
Manual (ad-hoc)
# Start the daemon for a single repo
turnkey-composed start --mount-point ~/firefly/turnkey --repo-root . --backend fuse
# Work from the mount point
cd ~/firefly/turnkey
buck2 build root//...
# Stop
turnkey-composed stop
As a service (recommended)
# Install the service (runs on login)
turnkey-composed install --start
# Edit the config to declare your mounts
vim ~/.config/turnkey/composed.toml
With home-manager (declarative)
{
imports = [ turnkey.homeManagerModules.turnkey-composed ];
services.turnkey-composed = {
enable = true;
package = turnkey.packages.${system}.turnkey-composed;
mounts = {
myproject = {
repo = "/Users/me/src/myproject";
mountPoint = "/firefly/myproject";
};
};
};
}
Prerequisites
Linux
# Verify FUSE is available
ls /dev/fuse
# If missing, install fuse3
sudo apt install fuse3 # Debian/Ubuntu
sudo dnf install fuse3 # Fedora
macOS
Install FUSE-T (no kernel extension, works on Apple Silicon):
brew install macos-fuse-t/homebrew-cask/fuse-t
Mount points under /: macOS root is read-only. The daemon
automatically manages /etc/synthetic.conf entries and activates them
via apfs.util -t when a mount point like /firefly/turnkey is
requested. This requires sudo (the daemon prompts when needed).
For paths under ~ (e.g., ~/firefly/turnkey), no special setup is
needed.
Service Configuration
The service reads ~/.config/turnkey/composed.toml:
# Mount a project
[[mounts]]
repo = "/Users/me/src/myproject"
mount_point = "/firefly/myproject"
# Mount another project
[[mounts]]
repo = "/Users/me/src/other-project"
mount_point = "/firefly/other"
backend = "fuse" # Optional: "auto" (default), "fuse", or "symlink"
The daemon watches this file for changes. When you add a new [[mounts]]
entry, the daemon picks it up and mounts it automatically — no restart
needed.
Home-Manager Module
The declarative alternative to editing the TOML file directly:
{
imports = [ turnkey.homeManagerModules.turnkey-composed ];
services.turnkey-composed = {
enable = true;
package = turnkey.packages.${system}.turnkey-composed;
mounts = {
myproject = {
repo = "/Users/me/src/myproject";
mountPoint = "/firefly/myproject";
};
other = {
repo = "/Users/me/src/other";
mountPoint = "/firefly/other";
backend = "fuse"; # Optional
};
};
};
}
This generates the config file and manages the launchd agent (macOS) or systemd user service (Linux).
Service Management
# Install and start the service
turnkey-composed install --start
# Uninstall the service
turnkey-composed uninstall
# The service runs `turnkey-composed serve` which:
# - Reads ~/.config/turnkey/composed.toml
# - Builds cells via nix for each repo
# - Mounts all entries
# - Watches for config and manifest changes
How Cell Discovery Works
On startup, turnkey-composed:
- Runs
nix evalto list*-cellpackages from each repo's flake - Runs
nix buildto build all cells in a single invocation (~3-4s if cached) - Uses the Nix store paths to populate
external/in the FUSE mount
Cells are always built from the current flake state. The daemon watches
manifest files (go-deps.toml, rust-deps.toml, etc.) and rebuilds
cells automatically when they change.
Mount Structure
/firefly/myproject/
├── .buckconfig # Virtual - generated by layout
├── .buckroot # Virtual - marks Buck2 root
├── root/ # Pass-through to your repository
│ ├── src/
│ ├── docs/
│ ├── flake.nix
│ └── ...
└── external/ # Dependency cells (from Nix store)
├── godeps/
├── rustdeps/
├── prelude/
├── toolchains/
└── ...
Buck2 runs from the mount root. Source targets use the root// cell
prefix: buck2 build root//src/cmd/tk:tk.
CLI Reference
Single Mount
# Start (foreground)
turnkey-composed start --mount-point <path> --repo-root <path> [--backend fuse|symlink|auto]
# With explicit config file
turnkey-composed start --config <path>
Service Mode
# Run as a service (reads ~/.config/turnkey/composed.toml)
turnkey-composed serve [--config <path>]
# Install/uninstall the system service
turnkey-composed install [--start]
turnkey-composed uninstall
Control
turnkey-composed status # Check daemon status
turnkey-composed refresh # Trigger manual cell rebuild
turnkey-composed stop # Stop the daemon
Platform Notes
Linux
Uses native FUSE via /dev/fuse with the fuser Rust crate. Best
performance.
macOS
Uses FUSE-T with direct C FFI bindings to libfuse3. FUSE-T translates FUSE operations to NFS internally. No kernel extension required.
The daemon handles synthetic firmlinks automatically for mount points
under / (manages /etc/synthetic.conf and runs apfs.util -t).
Symlinks (CI / Fallback)
Fastest for CI. No daemon needed. Automatically selected when FUSE is unavailable.
Integration with IDEs
VS Code / Cursor
{
"go.goroot": "/firefly/myproject/root",
"rust-analyzer.linkedProjects": ["/firefly/myproject/root/Cargo.toml"]
}
IntelliJ / GoLand
Set the project root to the FUSE mount point for consistent path resolution.