Skip to content

Feature Flags

Feature flags are the primary way to configure Marchyo. Each flag enables a group of related packages, services, and configurations.

Option Default Description
marchyo.desktop.enable false Desktop environment (Hyprland, Wayland, audio, bluetooth, fonts)
marchyo.development.enable false Development tools (git, Docker, buildah, gh, virtualization)
marchyo.media.enable false Media applications (Spotify, MPV, etc.)
marchyo.office.enable false Office applications (Papers document viewer, Obsidian, Xournal++)
marchyo.shell.enable false (true with desktop) Quickshell desktop shell: bar, launcher, OSD, panels, notifications, lock (details)
marchyo.cli.enable true Install the marchyo user CLI system-wide
marchyo.emacs.enable false Emacs daemon with Hyprland integration (details)

A second group of flags default to true and only take effect when marchyo.desktop.enable is set. Set one to false to opt out of that part of the desktop:

Option Description
marchyo.menus.enable Power, session and central system menus
marchyo.utilities.enable Date/time and battery notifications, marchyo transcode, marchyo share
marchyo.reminders.enable marchyo reminder timers and their keybindings
marchyo.screensaver.enable Terminal screensaver on idle

When you enable marchyo.desktop.enable, related flags are automatically enabled at a lower priority using lib.mkDefault:

# Enabling desktop...
marchyo.desktop.enable = true;
# ...automatically enables these (you can override them):
# marchyo.office.enable = true;
# marchyo.media.enable = true;
# marchyo.webapps.enable = true;
# marchyo.shell.enable = true;

Since these use lib.mkDefault, you can override them:

{
marchyo.desktop.enable = true;
marchyo.media.enable = false; # Disable media despite desktop being on
}

Marchyo sets boot.loader.timeout to 0, so systemd-boot skips the menu and boots the default entry. Hold Space at power-on to open the menu.

A timeout stored in an EFI variable overrides boot.loader.timeout. A host that set one from the menu keeps the menu visible for that many seconds.

This is a default, so a host can choose its own value:

boot.loader.timeout = 3;

When marchyo.desktop.enable = true, Marchyo configures:

  • Hyprland — Wayland compositor with pre-configured keybindings and window rules. Press SUPER+K for a searchable, on-screen cheat sheet of all active keybindings (toggle with marchyo.keybindingsHelp.enable)
  • Audio — PipeWire with PulseAudio and ALSA compatibility
  • Bluetooth — Enabled and configured
  • Fonts — Curated set of fonts including Nerd Fonts
  • Theming — Jylhis design-system theming across GTK, Qt, terminals, TUIs, and Emacs, with runtime theme switching
  • Desktop shell: the unified Quickshell shell (bar, launcher, OSD, panels, notifications, lock, and polkit agent; see Desktop Shell). marchyo.shell.enable = false keeps only hyprlock and hyprpolkitagent, with no bar, OSD or notification daemon
  • Terminal emulator — Ghostty
  • Default applications — Configurable via marchyo.defaults.*

When marchyo.development.enable = true, Marchyo configures:

  • Git with Git LFS and GitHub CLI (gh)
  • Containers — rootless Podman (with podman-tui) or Docker, plus Buildah and Skopeo
  • Virtualization via QEMU/KVM (libvirtd), with virt-manager and virt-viewer
  • Build tools — GNU Make, CMake, GCC, pkg-config
  • Utilities — direnv (with nix-direnv), jq, yq, network debugging tools (nmap, tcpdump, netcat)

Marchyo does not install OBS Studio, Kdenlive or lazydocker. To add one, list it in environment.systemPackages:

environment.systemPackages = with pkgs; [ obs-studio lazydocker ];

The container backend is selectable and defaults to rootless Podman:

Option Default Description
marchyo.development.containers.backend "podman" "podman" (rootless, docker-compatible CLI) or "docker" (rootful daemon)
marchyo.development.containers.dockerGroup false Add Marchyo users to the root-equivalent docker group (Docker backend only)

The default rootless Podman backend needs no elevated group at all: it is daemonless, runs in a user namespace, and provides a docker compatibility shim so most workflows keep working unchanged.

To opt into the classic rootful Docker daemon instead:

marchyo.development.containers.backend = "docker";

Pick a default AI coding-agent CLI (installed only when development.enable is on). The chosen CLI is installed and $AI_AGENT is set to its command:

Option Default Choices
marchyo.defaults.aiAgent null "claude-code", "codex", "opencode"
marchyo.development.enable = true;
marchyo.defaults.aiAgent = "claude-code"; # installs the CLI, $AI_AGENT = "claude"