Editing your config
Ternix gives you a starting point, not a fixed result. After you download the generated files, all further changes happen in your editor. The cycle is always the same. Edit, rebuild, check the result.
Add a package
System-wide on NixOS, add names to environment.systemPackages in
configuration.nix.
environment.systemPackages = with pkgs; [
git
firefox
ripgrep # adding a tool is one line
];For one user with Home-Manager, use home.packages in the home configuration.
home.packages = with pkgs; [ ripgrep bat ];If you are unsure of a package's exact attribute name, search on the Ternix
Packages page or on
search.nixos.org/packages . The attribute
name is what goes in the list, and it is not always the marketing name of the
program. You can also search from the terminal. This needs the nix-command and
flakes experimental features, which the generated config enables.
nix search nixpkgs ripgrepSet an option
Options configure NixOS modules. Browse Options for what exists, then set the ones you want.
services.openssh.enable = true;
time.timeZone = "America/New_York";
networking.firewall.allowedTCPPorts = [ 80 443 ];search.nixos.org/options lists every option with its type and default value, which tells you exactly what a given option expects. Pay attention to the type. Assigning a string to a boolean option is the most common mistake and produces a clear type error at build time.
Split into modules
As a config grows, move sections into their own files and pull them in with
imports. Each imported file is a NixOS module with the same
{ config, pkgs, ... }: signature as the main file.
# configuration.nix
{
imports = [
./hardware-configuration.nix
./desktop.nix
./services/web.nix
];
}This keeps each file focused on one concern and makes modules reusable across
machines. The NixOS manual
covers the full module system, including options, config, and lib.mkIf
for conditional configuration.
Common system tasks
A few edits come up for almost everyone. Add a user with sudo rights and an SSH key.
users.users.alice = {
isNormalUser = true;
extraGroups = [ "wheel" ];
openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAA... user@host" ];
};Open firewall ports (an allowedUDPPorts list exists for UDP).
networking.firewall.allowedTCPPorts = [ 80 443 ];Enable the SSH daemon.
services.openssh.enable = true;Set the hostname and timezone.
networking.hostName = "nixos-host";
time.timeZone = "America/New_York";For anything else, the Finding packages and options page shows how to track down the right option.
Rebuild and read errors
On NixOS, rebuild the running system with this command.
sudo nixos-rebuild switch --flake .#nixos-hostBefore committing a change to the live system, test it without making it the default boot entry.
sudo nixos-rebuild test --flake .#nixos-hosttest applies the configuration to the running system immediately but does not
update the boot entry. Rebooting returns to the last generation set as the boot default.
When a build fails, read the last error line first. It usually names the offending attribute and the type it expected. The output looks like this.
error: value is a string while a boolean was expected, at /etc/nixos/configuration.nix:12:5Fix the attribute, rebuild, and repeat. Because the running system only changes
when a build succeeds, a failed build leaves everything untouched. If a
switch did go through but something broke, use this command to roll back to the previous
generation.
sudo nixos-rebuild switch --rollbackYou can also select any earlier generation from the boot menu at startup.
For Home-Manager standalone, run this rebuild command.
home-manager switch --flake .#useruser is the attribute name in the generated flake (homeConfigurations.user).
Rename it in flake.nix if you prefer a different one, and match it here.
Advanced
nixos-rebuild build produces the system derivation without activating it,
which is useful in CI or for inspecting the result before you switch.
nixos-rebuild build --flake .#nixos-hostnixos-rebuild dry-build shows what would be fetched or compiled without
downloading anything.
nixos-rebuild dry-build --flake .#nixos-hostTo test a full system in a virtual machine without touching your hardware, use these commands.
nixos-rebuild build-vm --flake .#nixos-host
./result/bin/run-nixos-host-vmThe runner script is named after networking.hostName in the config (here
nixos-host), not the flake attribute.
When you need a package built differently, reach for pkgs.<name>.override to
change arguments the package exposes, and overrideAttrs to patch the
derivation directly. Both are documented in the
Nixpkgs manual on overriding .
environment.systemPackages = [
# change a compile-time flag the package exposes
(pkgs.curl.override { http2Support = false; })
# patch the derivation directly
(pkgs.hello.overrideAttrs (old: {
patches = (old.patches or []) ++ [ ./my-fix.patch ];
}))
];lib.mkIf gates a block of configuration on any boolean option, keeping the
module self-contained. The block activates only when its condition holds. Here
the firewall rule is added only when SSH is enabled.
{ config, lib, pkgs, ... }:
{
config = lib.mkIf config.services.openssh.enable {
networking.firewall.allowedTCPPorts = [ 22 ];
};
}References while editing
- Nixpkgs manual , covering how packages are written, built, and customised.
- NixOS options search , listing every option with its type and default.
- NixOS manual , covering the full system configuration and module reference.
- Home-Manager manual , covering per-user configuration options and usage.
Continue to Flakes for how inputs and the lock file keep your config reproducible.