Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

The DrakeFlake logo

NixOS, tamed.

DrakeFlake is a desktop app for NixOS systems that are configured with a flake. It lets you:

  • search all NixOS options of your system, see their current value and change them,
  • change the Home Manager settings of the users on your host (when Home Manager is used as a NixOS module),
  • search packages from the nixpkgs your system uses, add them to the system or try them without installing,
  • see the inputs in your flake.lock, check them for updates and update them,
  • rebuild the system, go back to an earlier generation and free disk space.

Try it now

DrakeFlake needs NixOS on x86_64 or aarch64 and a flake-based system configuration. You can run it straight from the repository without installing anything:

nix run gitlab:garuda-linux%252Fapplications/drakeflake

On first start the setup assistant helps you pick your flake and host. To keep the app, install it.

What it changes

The app never edits the files you wrote yourself. Everything you change is written to generated files inside your system flake, by default drakeflake.nix next to your flake.nix (and, with a split layout, the files in a drakeflake/ folder next to it). Your host configuration imports the generated file once; the setup assistant shows the line to add and checks that it is in place.

Every generated file starts with this header:

# GENERATED by DrakeFlake - safe to delete.
# Hand edits inside this file are overwritten on next Apply.

The app only overwrites or removes .nix files that carry this header (or are empty), and only inside a flake. Files written before the app was renamed carry the old name in this line; they are recognised too. A file without the header is never replaced.

Because the generated settings are ordinary NixOS module code, you can read them at any time (Changes → Preview file), commit them to git with the rest of your flake, or delete them to undo everything the app did.

How changes flow

  1. You change an option or add a package. The change is staged: it is kept in a list, nothing is written yet.
  2. Staged values are checked against the option’s type in the background.
  3. On the Changes page you look at the list, preview the generated file and choose how to apply: switch now, on the next boot, until the next reboot, or only save or build.
  4. The app writes the generated files (keeping a backup of the previous ones) and rebuilds the system. The output appears in the Console.

Staged changes survive a restart of the app. They are kept separately for each flake and host.

The window

The sidebar on the left lists the sections: Options, Home Manager (only when the host uses Home Manager), Packages, Generations, Actions, Cleanup, Inputs, Changes, Configured, History, Console, Settings and About. On narrow windows the sidebar collapses to icons.

Details (of an option or a package) open in a second column next to the list. While the app evaluates your configuration or runs a command, a status bar at the bottom of the window shows what it is doing.

Installation and requirements

What you need

  • NixOS on x86_64 or aarch64. The package is built for x86_64-linux and aarch64-linux.
  • A flake-based system configuration in a local folder: a flake.nix that defines nixosConfigurations.<hostname> for this machine. /etc/nixos is the default; any folder works, for example one in your home folder.
  • git, if your flake is a git repository. Flakes only see files that git tracks, so the app marks the generated files for git (see Reviewing and applying). The package brings its own git and curl for this and for update checks.
  • A way to get administrator rights for applying: a setuid pkexec (on NixOS this comes with polkit), otherwise run0, otherwise sudo. See Privacy and security.
  • nh (programs.nh.enable = true;). With nh you get Review and apply (a summary of what changes before switching, with a confirmation), and nh is also used for switching generations and for Cleanup. Without nh the app builds with nixos-rebuild, switches generations through its own helper and cleans up with nix-collect-garbage. The Actions page recommends installing nh when it is missing.

Optional

  • nvd: used by Generations → Compare when installed; otherwise the app uses nix store diff-closures.
  • nix-index: Packages → Search by command uses nix-locate. If it is not installed, the app builds it from your system’s nixpkgs when needed. The command database itself can be downloaded from the Packages page.
  • QEMU: Actions → Start in VM uses qemu-system-<arch> (for example qemu-system-x86_64) when it is installed; otherwise it is built from your system’s nixpkgs the first time.
  • A terminal emulator (for example Konsole): Try it opens command-line tools in a terminal, and opening a file in a terminal editor ($VISUAL or $EDITOR) needs one too.
  • Home Manager as a NixOS module, if you want to change Home Manager settings (see Home Manager).

Getting the package

The repository is a flake whose output packages.<system>.default is the app. It contains three programs:

  • drakeflake: the app, with a menu entry called DrakeFlake (category System),
  • drakeflake-tray: the small tray icon that checks for updates (see Flake inputs),
  • drakeflake-helper: the helper that does the few things that need root. It is not put on your PATH; the app runs it through pkexec (or run0 or sudo).

Install it system-wide

Add the repository as an input of your system flake and the package to environment.systemPackages. Use the URL you got this repository from:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    drakeflake.url = "gitlab:garuda-linux%252Fapplications/drakeflake";
  };

  outputs = { nixpkgs, drakeflake, ... }: {
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        ./configuration.nix
        (
          { pkgs, ... }:
          {
            environment.systemPackages = [
              drakeflake.packages.${pkgs.stdenv.hostPlatform.system}.default
            ];
          }
        )
      ];
    };
  };
}

Installing it system-wide also installs the app’s polkit actions (share/polkit-1/actions/org.garuda.drakeflake.policy), which give the password prompts a clear description and let polkit remember your password for a short while when saving files. See Privacy and security.

Try it from a checkout

To run the app without installing it, run this in a checkout of the repository:

nix run .

The app works the same way, but because its polkit actions are not installed, the password prompts are the generic ones of pkexec.

First start: the setup assistant

The setup assistant opens on the first start when there are no saved settings yet and there is no flake in /etc/nixos. You can open it again at any time from Settings → Setup assistant….

It has three steps: Requirements, System and Import.

1. Requirements

The first step lists what the app needs: a system flake, a host already set up in it, and, for Home Manager settings, Home Manager imported as a NixOS module.

Meanwhile the app looks for system flakes (flakes that define nixosConfigurations) in /etc/nixos, in the usual places in your home folder and a few folder levels below it. If it finds none, it says so; you can still choose the folder in the next step, or create a flake first, for example with sudo nixos-generate-config --flake.

Click Next.

2. System

System flake

The flakes the scan found are listed under Found:. Pick one, type a path into Folder:, or click Browse… to choose the folder. Then click Use this flake. The app reads the hosts of the flake, which can take a moment.

Host

Choose the configuration of this machine under Host:. The host whose name matches this computer’s host name is preselected when there is one.

Folder for the generated files

This is where the app writes its files. It must be inside the flake, because a flake can only import files from its own folder.

  • Leave the field empty to use the top folder of the flake. The settings are then written to drakeflake.nix next to flake.nix; with a split layout, their parts go into a drakeflake/ folder next to it.
  • Choose another folder (type it, or click Browse…) to keep the generated files apart. With a split layout the settings are written to default.nix in that folder with their parts next to it, so you import the folder itself; with the single-file layout they go into drakeflake.nix in that folder.

If the folder does not exist yet, click Create folder.

File layout

Choose how the settings are split over files:

  • Area and module: one file per area and module, for example services/openssh.nix and networking/firewall.nix.
  • By area: one file per area, for example services.nix and networking.nix.
  • Single file: everything in one file.

Packages you add go into packages.nix with the split layouts. You can change the layout and add your own rules later in Settings.

Click Next.

3. Import

Your changes only take effect once your host configuration imports the generated file. This step shows the line to add, for example:

imports = [ ./drakeflake.nix ];

Add it to the configuration of your host, for example in its configuration.nix. If the file already has an imports list, add the path to that list. The path shown is relative to the top folder of the flake; if the file that holds the import lives in a subfolder, adjust the path accordingly.

Then click Check import. The check:

  1. writes the generated file if it does not exist yet,
  2. adds it to git, because flakes only see tracked files,
  3. evaluates your host to see whether it really imports the file.

When the check succeeds you see “… imports the generated file. You are all set.” and can click Finish. If the host does not import the file yet, add the line, save the file and click Check import again.

You can also click Finish later and add the import afterwards. Until then the Changes page warns that your configuration does not import the file, and applying refuses to rebuild (Save only still works).

Searching and changing options

The Options page lists every NixOS option of your host. The first time, the app builds an option index from your system flake, which can take a minute; afterwards it is cached and only rebuilt when your flake changes.

Searching

Type into the search field (Search … options…). Each word you type must appear in the option’s name or description; the best matches come first. The line under the filters shows how many options match. Long result lists end with a Show more (… left) button.

Each row shows the option name, the start of its description and some tags:

  • its type (for example boolean or list),
  • = …: its current value, once values are evaluated,
  • set in config: your own configuration sets it,
  • managed: the app’s generated file sets it,
  • staged or staged reset: you have a change for it that is not applied yet,
  • read-only: it cannot be set.

Filters

  • All areas: click to limit the list to one area, such as services or boot. The list of areas can be filtered by typing.
  • Set in my configuration: show only options your own files define. It becomes available once the current values are evaluated.
  • Include <name> templates: also show options of named entries, such as users.users.<name>.shell. These cannot be set directly; search for the concrete name instead (for example users.users.alice.shell) or set them in your own configuration.

The refresh button at the top re-evaluates options and values.

The details page

Click an option to open its details next to the list.

The page shows:

  • the full name, the type and tags such as set in your configuration, managed by DrakeFlake or change staged,
  • the description,
  • Current value: the value your configuration evaluates to. It is evaluated when you open the option. If that fails, you see the error and a Try again button.
  • Set in:: the files of your configuration that set the option, with the line. Click one to open it in your editor (see Where is this set?).
  • Default, Example and Declared in: the option’s documentation. For options from nixpkgs, Declared in links to the module on GitHub.

The buttons at the top copy the option name (Copy name), evaluate the value again (Re-evaluate) and close the page (Close).

Changing an option

The Change section has these fields.

Enter as

  • Value: enter a plain value with an editor that fits the type: a switch for booleans (Enabled/Disabled), a number field, a list to choose from for enumerations, a text field for strings and paths, and one item per line for lists. For package options, type the package attribute, for example firefox or kdePackages.kate. Options that can be null have an Unset (null) box.
  • Nix expression: type any Nix expression. config, lib and pkgs are in scope, so you can write for example config.networking.hostName + "-vm". The expression is written as typed (in parentheses), and it is parsed and type-checked before saving.

Options whose type has no simple editor (shown with the type raw) are always entered as a Nix expression; they are syntax-checked before saving.

Priority

NixOS merges the definitions of an option from all files of your configuration. Priority decides how the app’s setting combines with yours. The choices depend on the option:

PriorityWhat it does
OverrideWins over your configuration (lib.mkOverride 90)
DefaultYour configuration wins (lib.mkDefault)
NormalSame priority as your configuration; different values conflict
ForceWins over everything (lib.mkForce)
Add (merge)Added to the items of your configuration
Add firstAdded before the other items (lib.mkBefore)
Add lastAdded after the other items (lib.mkAfter)
ReplaceReplaces what your configuration defines (lib.mkForce)

If you do not choose one, single values use Override and lists and attribute sets use Add (merge). The hint next to the field explains the chosen priority.

Applies to

If several hosts import the same generated file, you can limit a setting to this host:

  • All hosts that import the file: every host that imports the generated file gets the setting.
  • Only this host (…): the setting is written under lib.mkIf (config.networking.hostName == "…"), so other hosts importing the file ignore it.

“Only this host” needs the evaluated networking.hostName of your system, so it becomes available a moment after the page opens. It is not offered for networking.hostName itself.

Staging

  • Stage change (or Update staged change): put the change into the list on the Changes page. Nothing is written yet.
  • Revert: undo your edits in the editor.
  • Unstage: drop the staged change.
  • Remove from DrakeFlake file: for an option the generated file already sets, stage its removal. The option then goes back to whatever the rest of your configuration defines.

Type checks

Values are checked twice:

  • While you type, the value is checked against the option type. An invalid value shows the reason, and Stage change stays disabled.
  • After staging, the app checks the value against your configuration’s option types in the background. The result appears under the buttons (“Matches the option type”) and on the Changes page. Changes cannot be applied while a staged value does not match its type.

Where is this set?

Under Current value, Set in: lists the files that define the option, with a line number. The app finds the line from the file’s syntax tree (nested attribute sets, config = … and lib.mkIf/lib.mkMerge wrappers included). Files that come from a flake input instead of your own flake are marked “(flake input, read-only)”.

Clicking a location opens the file at that line:

  1. in your default text editor, when it is one that can jump to a line (Kate, KWrite, VS Code, VSCodium, Zed, GNOME Text Editor or Emacs),
  2. otherwise in $VISUAL or $EDITOR in a terminal,
  3. otherwise with the default app for .nix files.

Everything your host sets: the Configured page

The Configured page lists every option your host’s own configuration files define, with its current value and the file it is set in. Use the filter field to narrow it down and click an option to open its details. The first run can take several minutes; afterwards it is cached.

Packages

The Packages page searches the packages of the nixpkgs your system uses, so what you find is exactly what your system would install. Indexing takes a few seconds the first time.

Searching

Type a name or a word from the description into the search field. Each row shows the package name, its version and description, and tags:

  • installed: your system already has it,
  • added by DrakeFlake: the generated file installs it,
  • will be added / will be removed: a staged change.

The line next to the filters shows the number of matches and of installed packages.

Filters

  • Top-level packages: click to choose a package set instead, such as python313Packages, haskellPackages or vimPlugins. A set is indexed the first time you choose it and kept until your flake changes.
  • Installed only: show only packages your system has.
  • Search by command: find the package that provides a program, for example rg finds ripgrep. Programs are matched by their exact name in bin/.

Search by command

This search uses the nix-index database. If you do not have one (in ~/.cache/nix-index), the page offers to Download it: a prebuilt database from the nix-community/nix-index-database project on GitHub, about 100 MB, updated weekly. The app keeps its copy in ~/.cache/drakeflake/nix-index.

Adding and removing packages

  • To add a package, click Add in its row, or Add to system on its details page. The change is staged; apply it on the Changes page.
  • To remove a package the app added, click Remove (or Remove from system).
  • To take back a staged addition or removal, click Undo.

The app only removes packages it added itself. Packages installed by your own configuration show From your config in the list and Installed by your configuration on the details page; remove those in your own files.

Added packages are written as environment.systemPackages into the generated file (into packages.nix with a split layout).

Packages from a package set are mostly libraries. They usually belong in an environment, for example python3.withPackages, rather than directly in the system packages; the details page reminds you of this.

Package details

Click a package to see its details: description, the program it runs, license, homepage, maintainers, outputs and the file in nixpkgs that defines it. Tags show whether it is unfree or marked broken. Homepage at the top opens the project’s website.

Try it

Try it runs a package without installing it. It is offered for packages that declare a program to run.

The app builds the package from your system’s nixpkgs (progress is in the Console) and starts it when it is ready:

  • an app with a desktop entry opens as a window,
  • command-line tools open in a terminal with the package’s programs available.

Tried packages are kept so they start quickly next time. To free their space, use Cleanup → Remove tried packages.

Home Manager

When your host uses Home Manager as a NixOS module, the sidebar shows a Home Manager section. It lists the Home Manager options of the users on this host.

Requirements

  • Home Manager is imported as a NixOS module (home-manager.nixosModules.home-manager) in your host configuration.
  • Your user is set up in home-manager.users.<name>.

A standalone Home Manager setup (with its own home-manager switch) is not managed by the app.

Using it

The page works like the Options page: a search field, the area filter, Set in my configuration and Include <name> templates. Names are shown relative to the user, so you see programs.git.enable instead of home-manager.users.alice.programs.git.enable. If several users have Home Manager, choose the user in the list next to the search field.

Click an option to open its details. Changing it works exactly as described in Searching and changing options: choose a value or a Nix expression, a priority and, if needed, the host, then Stage change.

Where the settings go

Home Manager settings are written into the same generated files as your NixOS settings, as home-manager.users.<name>.…, and are applied with the next system rebuild. With a split layout they go into a home-manager/<name>/ folder next to the other parts, using the same layout inside it.

Reviewing and applying

Everything you stage collects on the Changes page. The sidebar entry shows the number of pending changes, for example Changes (3).

The Changes page

At the top you see the system the changes are for (Target: flake and host) and the generated entry file (File:).

Pending changes lists each staged change: an option with its new value, a package to add or remove, or a setting to remove from the generated file. Under each option you see its priority, input mode and host scope when they are not the defaults, and the result of the type check. Click an option to open its details; click the undo button at the end of a row to unstage it.

Managed by DrakeFlake lists what the generated file already sets. To hand a setting back to the rest of your configuration, click the remove button next to it; this stages its removal.

Messages above the list warn you when something would keep your changes from working, for example:

  • “Your configuration does not import … yet”: add the import line (see the setup assistant).
  • “… is not tracked by git, so the flake cannot see it”: click Track in git.
  • The generated file is outside the flake, or the flake is not a local folder.
  • Some staged values do not match their option type. Fix or unstage them; until then you cannot apply.

Previewing the generated files

Click Preview file to see the files exactly as they would be written, with syntax highlighting. With a split layout, each file starts with a ### path line. Copy copies the whole preview.

Applying

The toolbar has the two common actions; the menu (⋮) has the others.

ActionWhat it does
ApplySave the files, build the system and switch to it now. It also becomes the default at boot.
Review and apply…Save the files, then let nh build, show what changes (packages, versions, size) and ask before switching.
Review and apply on next boot…Like the above, but the new system becomes the default from the next boot on.
Save onlyWrite the files without rebuilding.
Save and test buildWrite the files and build the system without activating it.
Apply until reboot (test)Build and activate the new system now, without making it the default at boot.
Apply on next bootBuild the system and make it the default from the next boot on.
Discard allDrop every staged change.

When you apply, the app:

  1. renders the generated files and checks their Nix syntax,
  2. refuses to rebuild if your configuration does not import the generated file (Save only still works),
  3. backs up the current entry file (see History),
  4. writes the files; if it may not write to the flake folder (for example a root-owned /etc/nixos), it asks for your password and writes them with the helper,
  5. marks new files for git (git add --intent-to-add),
  6. builds the system as your user, with nh os build or, without nh, nixos-rebuild build,
  7. activates the built system as root, asking for your password.

The window switches to the Console, where you follow the output. The status bar shows “Applying changes…” while it runs, and the console ends with Done. or with a failure message.

Review and apply with nh

Review and apply… runs nh os switch (or boot) with --ask inside the app. nh builds the system, prints the package differences and then asks whether to continue. The question appears as a bar above the console output with Yes and No buttons. Review needs nh; the app tells you to use Apply when nh is not installed.

The Console

The Console shows the output of everything the app runs for you: builds, updates, comparisons and cleanups. Each command is shown before its output.

  • Cancel stops the running command.
  • Copy copies the whole output; Clear empties the console.
  • Restore previous file appears after a failed apply: it puts the generated file back as it was before.

Password prompts

Most password prompts are your desktop’s polkit dialog. When there is no setuid pkexec, the app uses run0 or sudo instead and says so in the console. If such a program asks for your password in the console, a password bar appears above the output: type the password and click Send. The password is passed to the program only; it is never shown or written to the log, and the prompt line is hidden from the output.

See Privacy and security for what runs as root.

Git

Flakes only see files that git tracks. When the app creates a new generated file inside a git repository, it marks it with git add --intent-to-add, so the flake sees it without you committing anything. If that fails, the Changes page shows a warning with a Track in git button.

Commit the generated files together with the rest of your flake whenever you like; the app does not commit or push anything.

History and restoring

Every save keeps the settings it replaced. The History page lists these earlier states, newest first: when they were replaced, how many settings and packages they hold, and what restoring them would change.

To go back, click Restore. The app writes those settings back (and keeps the current ones in the history). Rebuild afterwards to use them, for example with Apply on the Changes page.

The backups are stored outside the flake, in ~/.local/state/drakeflake/backups/ (or under $XDG_STATE_HOME when it is set), so they are never imported or committed.

Flake inputs

The Inputs page lists the inputs of your system flake from flake.lock: where each comes from, which revision it is locked to and when that revision was made, and whether upstream has something newer.

Checking for updates

Opening the page asks each source for its newest revision; Check for updates asks again. The check uses git ls-remote for git and GitHub sources and the HTTP headers of tarball sources. It takes a few seconds and needs the network.

Each input gets a tag:

  • update available: upstream has a newer revision. The row shows “Newest upstream: …” and, where the source supports it, a see all changes link to the comparison.
  • up to date
  • pinned: the input is locked to a fixed revision in flake.nix; there is nothing to update.
  • check failed: the source could not be asked, with the reason. Private repositories fail the check rather than ask for a password.

An input that follows another one (“Follows the input …”) is locked together with that input.

Inputs of inputs

Click a row with “… inputs of its own” to see the inputs that input brings along:

  • follows your …: it uses your input of that name,
  • same as your …: it shares the locked copy of one of your inputs,
  • follows …: it follows another input,
  • separate copy: it brings a second copy of a repository you already have as an input,
  • own copy: it brings its own copy of something you do not have.

For a separate copy, the app suggests the follows line that avoids the second copy, for example inputs.home-manager.inputs.nixpkgs.follows = "nixpkgs";.

Updating

  • To update one input, click Update in its row.
  • To update everything, click Update all at the top. It shows how many inputs can be updated, for example Update all (2).

The update runs nix flake update as your user, with the output in the Console. Cancel stops it, for example when a download hangs.

If your user may not write flake.lock (for example in a root-owned /etc/nixos), the new lock file is written to a temporary file first and then put in place by the helper, which asks for your password (“Save updated flake inputs”). The update itself never runs as root.

When the update succeeds, the page says “flake.lock was updated. Rebuild to start using the new versions.” with two buttons: Rebuild and switch and Build only. A rebuild from here uses your configuration as it is; it does not write the generated files.

Why updates use the newest known revision

A plain nix flake update asks GitHub’s API for the newest revision of a branch. When that API’s rate limit is reached, Nix prints “using cached version”, keeps the old revision and still reports success.

To avoid this, the app locks every input whose newer revision the check already found directly to that revision (with --override-input, which keeps the original reference such as github:NixOS/nixpkgs/nixos-unstable in flake.lock). Only the inputs without a known newer revision are left to nix flake update.

After the update the app compares flake.lock with what it expected. If an input did not reach the new revision, the console says “Not updated: … Nix kept its cached version”.

GitHub API rate limit

GitHub allows only a small number of anonymous API requests per hour. If your updates keep hitting the limit, give Nix a GitHub access token in nix.conf. A token without extra permissions is enough for public repositories:

access-tokens = github.com=ghp_yourtokenhere

Put it in a file only you can read, for example ~/.config/nix/nix.conf, rather than in your system configuration, which ends up in the world-readable Nix store.

Update notifications in the tray

drakeflake-tray is a small tray icon (not the whole app) that checks your flake inputs for updates: two minutes after it starts and then every six hours. When updates are available it changes its icon and shows a desktop notification (“Flake updates available”) naming the inputs. It notifies again only when the list of updatable inputs changes.

Its menu has Open DrakeFlake, Check for updates now and Quit. Only one tray runs per session.

To start it with your session, open Settings → Update notifications and turn on Start at login. This writes an autostart entry (~/.config/autostart/drakeflake-tray.desktop); turning it off removes it. Start it now starts the tray right away.

The tray checks the same flake as the app (from the app’s settings) and only works for a flake in a local folder. To test the check from a terminal, run drakeflake-tray --check-once; it prints the inputs that can be updated and exits.

Generations, cleanup and actions

Generations

Every rebuild creates a generation of your system. The Generations page lists them (read from /nix/var/nix/profiles), newest first, with their date, NixOS version, kernel and specialisations. Tags mark the generation that is running, the one that is the default at boot and the one that was booted.

For every other generation you can:

  • Compare: list what differs from the running system (packages added, removed and changed, and the size). This uses nvd when it is installed, otherwise nix store diff-closures. The result is in the Console.
  • Test: run that generation until the next reboot.
  • Boot: make it the default from the next boot on.
  • Switch to: both: run it now and make it the default. With nh this runs nh os rollback --to that generation.

Test, Boot and Switch to ask for your password. If you activated a system with Test, the page notes that the running system is not one of the listed generations; it is replaced by the default generation at the next boot.

Cleanup

The Cleanup page shows how much space is free on the disk that holds the Nix store and how many system generations you have.

To free space:

  1. Set Keep at least: the number of newest generations to keep.
  2. Set And everything from: the number of days whose generations are kept as well.
  3. Optionally turn on Also deduplicate the store (slow, saves space).
  4. Click Clean up….

This runs nh clean all: it removes older generations, then everything nothing uses any more. nh lists what goes and asks before deleting; answer with Yes or No in the Console. Old boot menu entries disappear with the next rebuild.

Without nh, the app runs nix-collect-garbage --delete-older-than with the number of days instead; the number of generations to keep and the deduplication are then ignored.

Remove tried packages (…) frees the packages you started with Try it on the Packages page.

Actions

The Actions page holds one-off tasks and recommendations.

Create images

You can build your system as an image: a live or installer ISO, a VM disk, an SD card image, a container or a cloud image. The list of formats comes from your NixOS version (its built-in image builder, system.build.images).

  1. Choose the system (this host or another host of your flake) and the format.
  2. Click Build image. Building can take a while; the progress is in the Console.
  3. When it is done, the page shows “… image ready” with:
    • Save as…: copy the image somewhere,
    • Show in folder: open the folder that holds it,
    • Start in VM: boot it in QEMU. The image itself is not changed.

Recommendations

Once the current values of your configuration are evaluated, the app suggests improvements that your configuration does not have yet, for example:

  • installing nh,
  • deduplicating the Nix store automatically,
  • cleaning up old generations automatically,
  • turning on the NixOS manual,
  • fixing option documentation that fails to evaluate,
  • removing old generations when many are kept,
  • updating nixpkgs when it is old.

Each suggestion has a button: Stage this change stages the setting and opens the Changes page (apply it like any other change), Open goes to the page that handles it, and Show them opens the options concerned on the Options page. When there is nothing to suggest, the page says so.

Settings

System

  • System flake: the folder that holds your flake.nix. Browse… opens a folder chooser.

  • Host: the configuration of this machine (nixosConfigurations.<host>). Choose it from the list or type its name.

  • Output file: where the app writes its generated entry file. Leave it empty for the default, drakeflake.nix next to flake.nix.

    • Choose file…: pick a .nix file.
    • Choose folder…: pick a folder. With a split layout the app writes default.nix there (so you import the folder); with a single file it writes drakeflake.nix there.
    • Use default: clear the field.

    The file must be inside the flake. Writes to: shows the file that will actually be written.

  • Use this system: switch to the flake, host and output file entered above. Staged changes are kept per system, so switching does not lose them.

  • Reload data: read options, values and packages again.

  • Rebuild caches: forget the cached option, value and package indexes and evaluate everything again.

  • Setup assistant…: open the setup assistant.

Generated files

File layout: decides how the settings are split over files:

  • Area and module (services/openssh.nix): one file per area and module. Options with a short name, such as networking.hostName, go into the area’s file (networking.nix).
  • By area (services.nix): one file per top-level area.
  • Single file: everything in the entry file.

With a split layout, the entry file only imports the other files, which live in a folder next to it: drakeflake/ for drakeflake.nix, or the same folder when the entry file is a folder’s default.nix. Packages go into packages.nix; Home Manager settings use the same layout inside home-manager/<user>/.

Custom rules: one rule per line, in the form prefix = file.nix. Settings whose option name starts with the prefix go into that file, in the folder next to the output file. Rules win over the layout, and when several rules match, the one with the longest prefix applies. Use environment.systemPackages as the prefix to move the package list. Lines starting with # are comments. For example:

services.openssh = remote-access.nix
environment.systemPackages = apps.nix

File names may use letters, digits, ., _, - and /; .nix is added when missing.

Click Save layout to use the new layout. It takes effect with the next save. If the change means the entry file is renamed (drakeflake.nix and default.nix in an output folder), the app removes the old generated entry file and its parts, and tells you to change your import.

Update notifications

Tray icon: turn on Start at login to start drakeflake-tray with your session. Start it now starts it right away. See Update notifications in the tray.

Code highlighting

Theme: the syntax highlighting theme for Nix code in previews, values and the Console. Automatic follows your desktop: under Plasma it picks the highlighting theme whose name matches your colour scheme or global theme (for example Catppuccin Mocha), otherwise Breeze Light or Breeze Dark by the brightness of your colours. Preview: shows the chosen theme.

Troubleshooting

  • Log detail: how much the app writes to its log file: Errors only, Warnings, Normal (recommended), Debug: every command run or Trace: also full command output. Debug messages from the interface itself are added after a restart.
  • Open log opens the log file; Show folder opens the folder that holds it.

See Troubleshooting for where the log is.

The configuration file

The settings are stored in ~/.config/drakeflake/config.toml (or under $XDG_CONFIG_HOME when it is set). The app writes it for you; you normally do not need to edit it. Missing keys take their defaults.

[general]
highlight_theme = ""       # empty: automatic
log_level = "info"         # error, warn, info, debug or trace

[nix]
flake_path = "/etc/nixos"  # the system flake
host = "laptop"            # the host; omit to choose it automatically
managed_path = "/etc/nixos/modules/"  # output file or folder; omit for the default

[layout]
mode = "area-module"       # single, area or area-module

[[layout.rules]]
prefix = "services.openssh"
file = "remote-access.nix"
KeyMeaning
general.highlight_themeName of the highlighting theme; empty for automatic.
general.log_levelDetail of the log file: error, warn, info (default), debug or trace. Also used by the tray.
nix.flake_pathThe system flake. Default /etc/nixos.
nix.hostThe host to manage.
nix.managed_pathThe output .nix file, or a folder (an existing one, or a path ending in /). Unset: drakeflake.nix next to flake.nix.
layout.modesingle, area or area-module (default).
layout.rulesCustom rules, each with prefix and file.

Environment variables

For testing and special setups, these variables override the saved settings when the app starts:

VariableEffect
DRAKEFLAKE_FLAKEUse this flake instead of the saved one.
DRAKEFLAKE_HOSTUse this host.
DRAKEFLAKE_MANAGED_FILEUse this output file or folder.
DRAKEFLAKE_SETUP=1Open the setup assistant on start.
DRAKEFLAKE_SOFTWARE_RENDERING=1Draw the window with the software renderer.
DRAKEFLAKE_EVAL_JOBSHow many evaluations run at once (normally chosen by CPU count and free memory).

Troubleshooting

The log file

Everything the app does is written to a log file:

  • the app: ~/.local/state/drakeflake/drakeflake.log
  • the tray: ~/.local/state/drakeflake/drakeflake-tray.log

($XDG_STATE_HOME/drakeflake/ when XDG_STATE_HOME is set.)

When a log reaches 5 MiB it is rotated: the older logs are kept as .1, .2 and .3, and the oldest one is dropped. Started from a terminal, the app also prints its log there.

To get more detail, set Settings → Troubleshooting → Log detail to Debug: every command run (every command the app runs) or Trace: also full command output. Open log and Show folder take you to the file. Passwords you type into the console are never logged.

“No system selected”

The pages show “No system selected” with the reason when the app cannot read your flake or host, for example because the folder does not exist or the flake does not evaluate. Click Open Settings, check System flake: and Host:, and click Use this system.

“The flake does not import the generated file”

Your changes only take effect when your host configuration imports the generated file. Until then the Changes page warns “Your configuration does not import … yet”, and applying stops with “Not rebuilding: the flake does not import …” (Save only still works).

  1. Open the configuration of your host, for example configuration.nix.
  2. Add the generated file to its imports, for example imports = [ ./drakeflake.nix ];. The path is relative to the file that contains the import. If the output is a folder with a default.nix, import the folder.
  3. Save the file. If your flake is a git repository and the generated file is new, make sure git tracks it (the app does this when it writes the file; otherwise click Track in git on the Changes page).
  4. Open Settings → Setup assistant… and use Check import on the last step to confirm.

If you changed the file layout or the output location, the name of the entry file may have changed (drakeflake.nix or a folder’s default.nix); the console tells you which import to use.

“… is not tracked by git, so the flake cannot see it”

Flakes ignore files git does not track. Click Track in git on the Changes page, or run git add --intent-to-add on the file yourself.

Applying failed

The Console shows the output of the failed build or switch; the last lines usually name the problem. After a failed apply:

  • Restore previous file puts the generated file back as it was before the apply.
  • Earlier states are on the History page, see History and restoring.
  • If the build itself fails, your running system is not changed.

An input was not updated

If the console says “Not updated: … Nix kept its cached version”, Nix could not get the new revision, usually because GitHub’s API rate limit was reached. Wait a while and update again, or give Nix a GitHub access token, see GitHub API rate limit.

The banner “This program is older than its interface files”

The app’s program and its interface files come from different versions, for example after updating while an old build is still started. Pages would call functions the program does not have, so the app shows this banner instead. Start the matching version: after updating the package, rebuild your system and start the app again; if you run it from a checkout, rebuild it there.

Slow first start

The first time, the app builds an option index from your flake, evaluates the values of the options your files define and indexes packages. This can take a minute or more; the status bar at the bottom shows what is running. Afterwards the results are cached in ~/.cache/drakeflake/ and only the parts that changed are evaluated again.

If the cache looks wrong, use Settings → Rebuild caches.

The status bar may say that some options are skipped because they fail to evaluate. If many option descriptions fail (often because of the removed lib.mdDoc), building the index is slow; the Actions page then recommends fixing them.

The window stays empty or the app does not start

If hardware-accelerated drawing does not work, the app falls back to software rendering by itself. To force it, start the app with DRAKEFLAKE_SOFTWARE_RENDERING=1 drakeflake.

Where things are

WhatWhere
Settings~/.config/drakeflake/config.toml
Log files~/.local/state/drakeflake/*.log
Backups of the generated settings~/.local/state/drakeflake/backups/
Staged changes~/.local/state/drakeflake/staged/
Caches (option and package indexes, tried packages, command index)~/.cache/drakeflake/
Tray autostart entry~/.config/autostart/drakeflake-tray.desktop

Privacy and security

What the app changes

The app edits nothing in your configuration except its own generated files. They are .nix files inside your flake that start with the line # GENERATED by DrakeFlake - safe to delete.. A file without that line is never overwritten or removed. Besides those, the app writes flake.lock when you update inputs, and its own settings, logs, backups and caches in your home folder (see Where things are).

What runs as your user

Almost everything runs as you, without extra rights:

  • evaluating your configuration, searching options and packages,
  • building the system (nh os build or nixos-rebuild build),
  • updating flake inputs (nix flake update): this deliberately never runs as root, so root never fetches the inputs your flake names into the store,
  • checking for updates, building images, “Try it”,
  • writing the generated files when you may write to the flake folder.

What runs as root

For the few steps that need root, the app uses a small helper, drakeflake-helper, started through pkexec. It can do exactly three things, and each has its own polkit action, so the password prompt tells you what is about to happen:

PromptWhat the helper doesPassword remembered?
Save system settings: “Authentication is required to save the generated NixOS settings files”Writes or removes generated .nix files in a flake you may not write to yourself, for example a root-owned /etc/nixos.Yes, for a short time
Activate a NixOS configuration: “Authentication is required to activate this NixOS configuration: …” (with the command)Activates a system that was already built, by running that system’s own switch-to-configuration (for switch and boot it also becomes the default boot entry).No, it asks every time
Save updated flake inputs: “Authentication is required to save the updated flake.lock”Replaces flake.lock with the new lock file your update produced.Yes, for a short time

The helper checks what it is asked to do before doing anything:

  • it only writes .nix files given as absolute paths without .., inside a flake, that are not symlinks, and only replaces or removes files that are empty or carry the generated header; the new content must be a generated module with valid Nix syntax,
  • it only activates systems in the Nix store that are complete NixOS systems,
  • it only installs a lock file that has the shape of a flake lock file, into a local folder that contains a flake.nix.

The polkit actions are only known to polkit when the package is installed system-wide (see Installation).

Some tasks are run by nh, which gets root itself when it needs it: Review and apply, Switch to on the Generations page and Cleanup. Without nh, Cleanup runs nix-collect-garbage as root, and applying without the helper lets nh or nixos-rebuild ask for root themselves.

pkexec, run0 and sudo

The app looks for a way to get root in this order:

  1. a setuid pkexec (on NixOS, /run/wrappers/bin/pkexec): your desktop’s polkit password dialog,
  2. run0 (systemd): also polkit, without a setuid program,
  3. a setuid sudo, only for commands that run in the Console.

When it is not pkexec, the console says which one is used. If run0 or sudo asks for your password in the console, answer in the password bar above the output (see Password prompts). The password goes to that program only and is never shown or logged.

Links in option descriptions, package metadata and flake inputs come from many sources. The app only opens links that start with http:// or https://; other links (for example file://) are not opened. Images in option descriptions are shown as their text, so viewing documentation does not load anything from the internet.

Network access

The app sends nothing about you or your system anywhere. It only uses the network for:

  • fetching your flake inputs and packages, done by Nix itself (evaluating, building, updating, “Try it”, images),
  • checking flake inputs for updates (git ls-remote and HTTP header requests to the sources named in your flake.lock), by the app and by the tray,
  • downloading the nix-index command database from GitHub, only when you click Download on the Packages page,
  • opening links in your browser when you click them.