Neil Lobo

shvl, an overview

Aug 22, 2026

3 min read


I’ve been daily driving NixOS for almost two years now and I’ve been loving it… for the most part. The one thing I find slightly annoying is that when I want to install a new package I need to open a text editor, manually update my config file (or files), save, rebuild my system, commit and push my changes (since I manage my configs in a git repo).


Since my config is a multi-system config with a common config that applies to all my systems, I now have two places where I could add a package to install on a single machine (the common folder or the machine specific folder).

nixos/
├── common/
│   └── configuration.nix
└── laptop/
    └── configuration.nix

Realistically, this isn’t much of an issue and becomes muscle memory after a certain point, but I couldn’t fight the thought of there being a nicer way to do this.


Lets get the obvious point out of the way, using nix-env -i or nix profile install to imperatively install packages to my nix profile. If you use NixOS and the word “imperatively” didn’t just send shivers down your spine then I have no idea why you’re using NixOS in the first place. I’ll leave it at that.


What if there was a way to add packages to my NixOS config that feels like using nix profile but still be declarative? The solution is actually pretty simple, a CLI tool that manages small .nix files that contain your lists of packages for you to import into your configs.

# .shvl/common.nix

pkgs:
(
    with pkgs;
    [
            audacity
            bat
            cachix
            jq
            obsidian
            openvpn
            ripgrep
            tokei
            vlc
    ]
)
nixos/
├── .shvl/
│   ├── common.nix
│   └── laptop.nix
├── common/
│   └── configuration.nix (imports .shvl/common.nix)
└── laptop/
    └── configuration.nix (imports .shvl/laptop.nix)

This is the main goal of shvl (pronounced shovel), a small CLI to manage lists of packages called “groups”. You can take a look at my own multi-system config for an example on how to use these group files.


With shvl I can now add/remove packages from my system without the need of opening a text editor, I simply run shvl add <package>, select the group I want to add the package to, and shvl handles the rest. For a more detailed explaination of available commands, I suggest reading the repo’s README

What’s next?

This is great and all, but if I don’t want to open a text editor to add a package to my system I don’t want to open a web browser to search for packages either! At the moment, I use nsearch to fuzzy find the packages I’m looking for, and can search and add a package with a single command: shvl add $(nsearch). nsearch is actually really nice but it would be even nicer if search was integrated with shvl directly. Though, that’s a problem for another time.