Introduction
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
- You change an option or add a package. The change is staged: it is kept in a list, nothing is written yet.
- Staged values are checked against the option’s type in the background.
- 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.
- 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-linuxandaarch64-linux. - A flake-based system configuration in a local folder: a
flake.nixthat definesnixosConfigurations.<hostname>for this machine./etc/nixosis 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
gitandcurlfor this and for update checks. - A way to get administrator rights for applying: a setuid
pkexec(on NixOS this comes with polkit), otherwiserun0, otherwisesudo. See Privacy and security.
Recommended
- 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 withnixos-rebuild, switches generations through its own helper and cleans up withnix-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 exampleqemu-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 (
$VISUALor$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 yourPATH; the app runs it throughpkexec(orrun0orsudo).
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.nixnext toflake.nix; with a split layout, their parts go into adrakeflake/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.nixin that folder with their parts next to it, so you import the folder itself; with the single-file layout they go intodrakeflake.nixin 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.nixandnetworking/firewall.nix. - By area: one file per area, for example
services.nixandnetworking.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:
- writes the generated file if it does not exist yet,
- adds it to git, because flakes only see tracked files,
- 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
booleanorlist), = …: 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
servicesorboot. 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 asusers.users.<name>.shell. These cannot be set directly; search for the concrete name instead (for exampleusers.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
firefoxorkdePackages.kate. Options that can benullhave an Unset (null) box. - Nix expression: type any Nix expression.
config,libandpkgsare in scope, so you can write for exampleconfig.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:
| Priority | What it does |
|---|---|
| Override | Wins over your configuration (lib.mkOverride 90) |
| Default | Your configuration wins (lib.mkDefault) |
| Normal | Same priority as your configuration; different values conflict |
| Force | Wins over everything (lib.mkForce) |
| Add (merge) | Added to the items of your configuration |
| Add first | Added before the other items (lib.mkBefore) |
| Add last | Added after the other items (lib.mkAfter) |
| Replace | Replaces 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:
- 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),
- otherwise in
$VISUALor$EDITORin a terminal, - otherwise with the default app for
.nixfiles.
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,haskellPackagesorvimPlugins. 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
rgfindsripgrep. Programs are matched by their exact name inbin/.
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.
| Action | What it does |
|---|---|
| Apply | Save 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 only | Write the files without rebuilding. |
| Save and test build | Write 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 boot | Build the system and make it the default from the next boot on. |
| Discard all | Drop every staged change. |
When you apply, the app:
- renders the generated files and checks their Nix syntax,
- refuses to rebuild if your configuration does not import the generated file (Save only still works),
- backs up the current entry file (see History),
- 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, - marks new files for git (
git add --intent-to-add), - builds the system as your user, with
nh os buildor, without nh,nixos-rebuild build, - 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
nvdwhen it is installed, otherwisenix 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 --tothat 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:
- Set Keep at least: the number of newest generations to keep.
- Set And everything from: the number of days whose generations are kept as well.
- Optionally turn on Also deduplicate the store (slow, saves space).
- 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).
- Choose the system (this host or another host of your flake) and the format.
- Click Build image. Building can take a while; the progress is in the Console.
- 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.nixnext toflake.nix.- Choose file…: pick a
.nixfile. - Choose folder…: pick a folder. With a split layout the app writes
default.nixthere (so you import the folder); with a single file it writesdrakeflake.nixthere. - Use default: clear the field.
The file must be inside the flake. Writes to: shows the file that will actually be written.
- Choose file…: pick a
-
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"
| Key | Meaning |
|---|---|
general.highlight_theme | Name of the highlighting theme; empty for automatic. |
general.log_level | Detail of the log file: error, warn, info (default), debug or trace. Also used by the tray. |
nix.flake_path | The system flake. Default /etc/nixos. |
nix.host | The host to manage. |
nix.managed_path | The output .nix file, or a folder (an existing one, or a path ending in /). Unset: drakeflake.nix next to flake.nix. |
layout.mode | single, area or area-module (default). |
layout.rules | Custom rules, each with prefix and file. |
Environment variables
For testing and special setups, these variables override the saved settings when the app starts:
| Variable | Effect |
|---|---|
DRAKEFLAKE_FLAKE | Use this flake instead of the saved one. |
DRAKEFLAKE_HOST | Use this host. |
DRAKEFLAKE_MANAGED_FILE | Use this output file or folder. |
DRAKEFLAKE_SETUP=1 | Open the setup assistant on start. |
DRAKEFLAKE_SOFTWARE_RENDERING=1 | Draw the window with the software renderer. |
DRAKEFLAKE_EVAL_JOBS | How 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).
- Open the configuration of your host, for example
configuration.nix. - Add the generated file to its
imports, for exampleimports = [ ./drakeflake.nix ];. The path is relative to the file that contains the import. If the output is a folder with adefault.nix, import the folder. - 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).
- 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
| What | Where |
|---|---|
| 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 buildornixos-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:
| Prompt | What the helper does | Password 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
.nixfiles 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:
- a setuid
pkexec(on NixOS,/run/wrappers/bin/pkexec): your desktop’s polkit password dialog, run0(systemd): also polkit, without a setuid program,- 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
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-remoteand HTTP header requests to the sources named in yourflake.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.