TB: Wrapper manager

Sean Borg July 05, 2026 [Tiny Blog] #Nix #wrapper manager

In my quest to remove all home manager I have found wrapper manager and thought I'd try document how I integrated it into my nixos config

I still feel like im learning nix if i'm doing anything crazy please email me, make an issue in this websites gitlab repo or if you understand radicle submit a pr/issue to my nixos config

My goal was to keep all my wrapped config in one directory, since I use krops and do some crazy stuff my nixos directory looks a bit like this

.
├── config
│   ├── configuration.nix
│   ├── readme.md
│   ├── channels
│   ├── hm-to-copy
│   ├── machine-specific
│   ├── my-pkgs
│   ├── public-keys
│   ├── roles
│   ├── sean
│   ├── vars
│   └── wrapped
│       ├── atuin.nix
│       ├── cib.nix
│       ├── ci-runner-radicle.nix
│       ├── firefox.nix
│       ├── fish.nix
│       ├── git.nix
│       ├── helix
│       │   ├── codebook
│       │   │   └── codebook.toml
│       │   ├── default.nix
│       │   └── helix
│       │       ├── config.toml
│       │       └── languages.toml
│       └── sherlock.nix
├── my-devices
└── tests

Then I can pull in all the wrapped stuff under the wrapped namespace by doing the following in the let statement of any nix file

importJson = (import <nixpkgs> { }).lib.importJSON;
wrapper-manager-git = builtins.fetchGit {
  rev = (importJson ../channels/wrapper-manager.json).rev;
  url = (importJson ../channels/wrapper-manager.json).url;
  allRefs = true;
};
wrapper-manager = (import "${wrapper-manager-git}");
wrapped = wrapper-manager.lib {
  inherit pkgs;
  modules = map (n: <path to wrapped folder>/${n}) (builtins.attrNames (builtins.readDir <path to wrapped folder>));
};

I'm making the assumption that repeating this in many files just gets squished into 1 at the end. Also the import json allows me to pin the repo and update it with 1 command like nix-shell -p nix-prefetch-git --command 'nix-prefetch-git --url https://github.com/viperML/wrapper-manager.git --rev refs/heads/master > config/channels/wrapper-manager.json'

Resulting in nix files like

{ config, pkgs, ... }:
let
  importJson = (import <nixpkgs> { }).lib.importJSON;
  wrapper-manager-git = builtins.fetchGit {
    rev = (importJson ../channels/wrapper-manager.json).rev;
    url = (importJson ../channels/wrapper-manager.json).url;
    allRefs = true;
  };
  wrapper-manager = (import "${wrapper-manager-git}");
  wrapped = wrapper-manager.lib {
    inherit pkgs;
    modules = map (n: ../wrapped/${n}) (builtins.attrNames (builtins.readDir ../wrapped));
  };
in
{
  # <snip>
  users.users.sean = {
    shell = wrapped.config.wrappers.atuin-fish.wrapped + "/bin/fish";
    packages = with pkgs; [
      wrapped.config.wrappers.touch-firefox.wrapped
      wrapped.config.wrappers.sean-helix.wrapped
      wrapped.config.wrappers.sean-git.wrapped
      wrapped.config.wrappers.atuin-fish.wrapped
      wrapped.config.wrappers.pc-atuin.wrapped
    }
  }
  # <snip>
}

Full file here