Note: This project is entirely generated and maintained by Gemini CLI under human guidance.
A lightweight, Go-based web interface designed specifically for managing Btrfs snapshots on NixOS via Snapper. This project aims to provide a clean, "File Explorer" style dashboard for users who want to visualize their snapshot history and perform granular file restorations without leaving the browser.
This WebUI should be treated as a privileged administrative surface. Prefer localhost-only binding or place it behind authenticated access control such as a trusted reverse proxy or Tailscale-based access layer. Do not expose it directly to the public internet without reviewing authentication, authorization, and network restrictions first.
- Snapshot Browser: List all snapshots for different Snapper configurations (e.g.,
home,var). - Diff Explorer: A tree-view file diff that allows you to see exactly what changed in each snapshot.
- Recursive UndoChange: Restore specific files or entire directories to a previous state with a single click.
- Snapshot Management: Create new manual snapshots with descriptions and custom userdata, or delete old ones.
- System Awareness: Real-time monitoring of Snapper config settings, cleanup schedules, and retention policies.
Unlike snapper rollback, this tool focuses on undochange. On NixOS, system-level rollbacks are traditionally handled via the bootloader generations.
Performing a Btrfs-level rollback (changing the default subvolume) on NixOS can lead to inconsistencies with fstab and the Nix store. To keep your system safe and "Nix-idiomatic," we recommend:
- Using Nix Generations for full system rollbacks.
- Using this WebUI (UndoChange) for granular data and configuration file recovery.
To run this WebUI, your system must meet the following criteria:
- Operating System: NixOS (Flake-based recommended).
- Filesystem: Btrfs.
- Core Utility:
snappermust be installed and active (the WebUI calls/run/current-system/sw/bin/snapper). - Permissions: The service must run as
rootto execute snapshot operations.
Add this repo to your flake.nix inputs:
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
btrfs-webui.url = "github:anton1615/Btrfs-Webui-for-Nixos";
# Ensure it uses your system's nixpkgs version to save space
btrfs-webui.inputs.nixpkgs.follows = "nixpkgs";
};
# ...
}In your configuration.nix (or any imported module), define the system package and the service.
Note: Modern NixOS (24.11+) recommends using stdenv.hostPlatform.system.
{ config, pkgs, inputs, ... }:
let
# Retrieve the package from the flake input
btrfs-webui-pkg = inputs.btrfs-webui.packages.${pkgs.stdenv.hostPlatform.system}.default;
in
{
# 1. Install the package
environment.systemPackages = [ btrfs-webui-pkg ];
# 2. Define the service
systemd.services.btrfs-webui = {
description = "Btrfs Snapshot Web Dashboard";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
# The binary is named 'Btrfs-Webui-for-Nixos'
ExecStart = "${btrfs-webui-pkg}/bin/Btrfs-Webui-for-Nixos";
User = "root"; # Required to run 'snapper' commands
Restart = "always";
WorkingDirectory = "/var/lib/btrfs-webui";
};
};
# Create necessary working directory
systemd.tmpfiles.rules = [
"d /var/lib/btrfs-webui 0750 root root -"
];
}Once deployed, the service will start automatically.
- URL:
http://localhost:8888 - Port:
8888(Hardcoded inmain.go) - Network: By default, it listens on all interfaces (
:8888). If you want to expose it securely, we recommend using Tailscale Serve or a reverse proxy.
This UI does not manage Snapper configurations (creating new configs or changing intervals). You should define your Snapper configs in your NixOS configuration using the declarative services.snapper.configs option.
- Backend: Go (Standard Library only).
- Frontend: Pure HTML/JS/CSS (Vanilla, no frameworks, encapsulated via Go
embed). - Snapper Integration: Calls
/run/current-system/sw/bin/snapperdirectly to ensure NixOS compatibility. - Tested Hardware: ASUS X550VC (Intel i5-3230M, 4GB RAM).
- Tested OS: NixOS 25.11 (Flake-based).
- License: MIT License.
Developed with ❤️ using Gemini CLI.
