2025-05-06
nix-index-database
not working well with the shallow clone... Other than that no issues after running for a few months.# flake.nix
inputs = {
nixpkgs.url = "git+https://github.com/NixOS/nixpkgs?shallow=1&ref=nixos-unstable";
};
# flake.nix
inputs = {
wallpapers = {
url = "git+ssh://git@github.com/TSawyer87/wallpapers.git";
flake = false;
};
}
inputs
argument and
something like path = "${inputs.wallpapers}/Aesthetic Scenery.jpg";
@-patterns
, being able to reference your outputs argument set as a whole. An
@-pattern
is a way for a function can access variadic attributes (i.e. varying number of
arguments).# flake.nix
inputs = {
home-manager.url = "github:nix-community/home-manager/master";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
stylix.url = "github:danth/stylix";
};
outputs = {
self,
nixpkgs,
home-manager,
} @ inputs:
With the above example to add the modules to your nixosConfigurations you would add something like this:
# flake.nix
nixosConfigurations.${host} = nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = {
inherit inputs username host email systemSettings;
};
modules = [
./hosts/${host}/config.nix
inputs.stylix.nixosModules.stylix
home-manager.nixosModules.home-manager
# .. snip ..
];
outputs = { self, nixpkgs, home-manager, };
the inputs
prefix is unnecessary.
If home-manager was removed from the outputs arguments: outputs = { self, ... }
then you would need modules = [ inputs.home-manager.nixosModules.home-manager];
This can be confusing
because many docs assume your not using an @-pattern so if you have one in your flake you need to prefix
with inputs
. I use this to reference my personal wallpapers repo mentioned earlier.specialArgs
(nixos) and extraSpecialArgs
(home-manager). Building on the @-patterns, using
specialArgs
and extraSpecialArgs
is a way to pass arguments from your flake to your NixOS and home-manager
modules.For example, here is a snippet of some variables I set:
# flake.nix
outputs = {
self,
nixpkgs,
home-manager,
...
} @ inputs: let
system = "x86_64-linux";
host = "magic";
username = "jr";
userVars = {
timezone = "America/New_York";
locale = "en_US.UTF-8";
gitUsername = "TSawyer87";
dotfilesDir = "~/.dotfiles";
wm = "hyprland";
browser = "firefox";
term = "ghostty";
editor = "hx";
keyboardLayout = "us";
};
in
Now I can pass them as special args like this:
# flake.nix
nixosConfigurations = {
${host} = nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = {
inherit
inputs
username
system
host
userVars
;
};
modules = [
./hosts/${host}/configuration.nix
home-manager.nixosModules.home-manager
inputs.stylix.nixosModules.stylix
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.${username} = import ./hosts/${host}/home.nix;
home-manager.backupFileExtension = "backup";
home-manager.extraSpecialArgs = {
inherit
inputs
username
system
host
userVars
;
};
}
];
userVars
for example:# git.nix
{ userVars, ... }: {
programs = {
git = {
enable = true;
userName = userVars.gitUsername;
};
};
}
checks
and formatter
outputs with treefmt-nix
. Add treefmt-nix
to your inputs and outputs arguments.
Inside the let
expression from tip 4 I would add:# flake.nix
let
# ... snip ...
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
};
treefmtEval = treefmt-nix.lib.evalModule pkgs ./treefmt.nix;
in
{
checks.x86_64-linux.style = treefmtEval.config.build.check self;
formatter.x86_64-linux = treefmtEval.config.build.wrapper;
# ... snip ...
}
And in the treefmt.nix
:
# treefmt.nix
{
projectRootFile = "flake.nix";
programs = {
deadnix.enable = true;
statix.enable = true;
keep-sorted.enable = true;
nixfmt = {
enable = true;
strict = true;
};
};
settings.excludes = [
"*.age"
"*.jpg"
"*.nu"
"*.png"
".jj/*"
"flake.lock"
"justfile"
];
settings.formatter = {
deadnix = {
priority = 1;
};
statix = {
priority = 2;
};
nixfmt = {
priority = 3;
};
};
}
Use treefmt-nix
to manage code formatters and linters as flake outputs. This ensures consistent styling
and catches issues with tools like deadnix
, statix
, and nixfmt
.
Use nix fmt
in the flake directory to format your whole configuration.
Now you can run nix flake check
to run your checks. Running nix flake show
will list your outputs.
Tools like nix-fast-build
rely on flake checks and can be used after setting this up.
in
{
checks.x86_64-linux.style = treefmtEval.config.build.check self;
formatter.x86_64-linux = treefmtEval.config.build.wrapper;
devShells.${system}.default = import ./lib/dev-shell.nix { inherit inputs; };
and in the dev-shell.nix
you could put something like this:
# dev-shell.nix
{
inputs,
system ? "x86_64-linux",
}:
let
# Instantiate nixpkgs with the given system and allow unfree packages
pkgs = import inputs.nixpkgs {
inherit system;
config.allowUnfree = true;
overlays = [
# Add overlays if needed, e.g., inputs.neovim-nightly-overlay.overlays.default
];
};
in
pkgs.mkShell {
name = "nixos-dev";
packages = with pkgs; [
# Nix tools
nixfmt-rfc-style # Formatter
deadnix # Dead code detection
nixd # Nix language server
nil # Alternative Nix language server
nh # Nix helper
nix-diff # Compare Nix derivations
nix-tree # Visualize Nix dependencies
# Code editing
helix
# General utilities
git
ripgrep
jq
tree
];
shellHook = ''
echo "Welcome to the NixOS development shell!"
echo "System: ${system}"
echo "Tools available: nixfmt, deadnix, nixd, nil, nh, nix-diff, nix-tree, helix, git, ripgrep, jq, tree"
'';
}
nix develop
or automatically with direnv
.