It’s quite new but I’ve been cooking up some new bootstrapping features with mise which people may find relevant here: https://mise.jdx.dev/bootstrap.html
It’s for things like dotfiles, apt/brew packages, and LaunchAgents/systemd.
EDIT: I feel a little bad having hijacked this, as someone that hears a lot of opinions about devtools I can definitely say chezmoi is a darling of the community and I highly recommend checking it out.
I saw it the other day in the release notes and I'm definitely setting this up since I already use mise for many of my global tools and projects.
Some months ago I ported part of my git bare repo to chezmoi but never really picked it up since, even if I see it as a great and very complete tool for managing complex dotfiles, I don't have many machines and can live by with a bunch of if uname -s, and the fact that I still need to wrangle brewfiles and scripts for packages. Having the sytem package managers glue along the configs and symlinks is exactly what I wanted.
I am quite intrigued. With the sorry state of security, I am doing everything in VMs and have been trying to settle on the best way to setup a new machine. The process is so clunky that I end up defaulting to bigger instances than I should (more pets than cattle).
Being able to centralize this config is far more attractive than having a separate Ansible or pyinfra process.
That still feels like more external tooling, plus letting the distro make my packaging decisions. I am already using mise, so this is an almost free boon without more complexity.
Just started moving things to mise and didn’t see this before, thanks.
Hopefully can use this alone instead of needing to combine w/ chezmoi / nix to get everything shell and pkg manager agnostic, consistent, and DRY (bash/zsh/fish + macports/pkgsrc/brew).
it's dependency free. You don't even need brew to install brew formulas.
The "exception" to that are linux package managers like apt-get and dnf which it calls under the hood. I think can't be an actual issue since it's not like you would ever use ubuntu/redhat without their system package manager installed.
Thanks so much for your work on mise! I used to be a heavy asdf user but nowadays I'm an even heavier mise user!
Random question while you're here: mise is undergoing pretty heavy development these days and I recently noticed that 1) my coworkers and I are not always on the same version, so some features/bug fixes are not available to everyone, and 2) package registries often don't have the latest mise version.
So I think we need a meta tool manager here to manage the tool manager version. :) Seriously, though, have you considered having mise manage its own version? I think that'd be pretty neat!
Thinking aloud, I guess one way to do this might be to distribute through package registries only a lightweight bootstrap application, which 1) reads the pinned mise version from mise.toml and downloads it as necessary, and 2) sets up a basic shell hook that the active mise version can then hook into(?) I know, this probably sounds a lot easier than it actually is.
Even just as a user of nix there has been this problem of how to manage dotfiles - people have git repositories for them but they are copies, because the actual dotfile in use is never tracked
For a System administrator the problem is many orders of magnitude worse
I'm pretty committed to the `nix` ecosystem (I rewrote `nix` from scratch to unbreak it: https://gist.github.com/b7r6/90107d8e8ebe81fb0577b9c033b6ab0..., so, pretty committed), but I can't endorse it in it's current form after learning how the sausage is made and enough math to know why it's not just buggy but conceptually unsalvagable with the current `nixpkgs` and the current purity dogma.
And `home-manager` is maybe the most glaring instance of a tool that is demonstrably ill-posed where the "you're holding it wrong" from the community is a the community problem, not anyone holding anything wrong. From the Zed editor configuration stanza in `home-manager`: https://github.com/nix-community/home-manager/blob/a78606767.... That's not a Zed problem, that's a Nix problem. No one is holding it wrong, XDG config paths get mutated.
There is absolutely nothing "impure" about taking content-addressed bytes from a CAS (Xet in this instance) and surfacing them as a derivation. The "impurity" is called a "coeffect" and the action over the coeffect is called "grade discharge". This is thoroughly studied and works properly, it can cope with all of these cases and it's creates scope for dramatically more reproducible systems that are much easier to reason about (they are possible to reason about). Also, if you can't download shit from HuggingFace in 2026 without a weird hack where the name of the field is a scolding? That's gonna be putting downward pressure on adoption.
And most of the high-friction shit in Nix is like this, ignorance hardened into dogma hardened into theology. To wit:
- FHS vs. zany one-of-a-kind filesystems are nothing to do with purity or hermeticity or reproducibility, it's pure theology and the constant breakage with all the `patchFail` jank is at this point a jobs program, it's totally unnecessary. Namespaces/unshare, we have all the stuff to do this properly (`patchelf` and `unshare --bind-mount` are mathematically dual but only one blows content addressing).
- `drv` hash addressing is a reproducibility war crime. Floating CA is fine it's just broken upstream and in Determinate, it's not a valid ideological debate, it's bugs.
- there is absolutely no reason why the builder where a binary is produced needs to have the same filesystem layout or find libraries in the same place as the resulting artifact runs in any more than an adult needs to live in the same house they grew up in. `patchelf` works.
- having `libcuda.so.1` and friends at `/run/opengl-driver/lib` is dark comedy and source builds of `NCCL` when NVIDIA-certified binaries are in a wheel (zip file) on PyPI is the sequel. this is straight up bad for the planet and we should feel bad we haven't fixed it.
I could go on, but the main point for this thread is to the people who are on the fence about Nix: you're not holding it wrong the `nixpkgs` maintainers are holding it wrong, and more and more of us are getting serious about fixing it. Don't give up on declarative and reproducible systems that you can reason about because Nix is stuck in a weird place as software and as a community. There are reformers on the case.
People shy from Nix because of supposed complexity but it really is the only real solution to this sort of problem. It's not really that much more difficult to learn, and in fact if you are willing, AI works really well generating nix config.
It took me a single afternoon to learn the basics and start using it. Contrary to what I initially thought, I didn't have to migrate all of my dotfiles at once. Then over the next couple of days, Codex migrated everything else for me.
One major benefit for me is that I no longer need to have once-in-a-while tools installed, because I can always spin up a temporary shell with `nix-shell -p packageName`. This significantly decreased the amount of software I have in my environment.
This works great with agentic coding. Agent wants to run `ripgrep`, but you don't have it? Tell it to run `nix run nixpkgs#ripgrep` instead.
But the biggest benefit is that now that you know Nix! So you can start using it to create reproducible development environments and uninstall mise, asdf, nvm, pyenv, etc. You can spin up reproducible servers running NixOS and never touch Ansible again. You can even install it in your router.
Or you can do none of that and continue just using it for your dotfiles. It plays nice with other tools.
It's not complexity its questionable documentation. Picking up Nix is really hard yet the best we got is a mishmash of unofficial recourses and many of them are out of date and/or focus on the packaging side which is terrible for introduction.
I spent a year dabbling in NixOS, getting a few "toy" setups.
About 6 weeks ago I installed NixOS on a spare laptop and did 100% of the configuration through Claude Codex. Initially I copied "/etc/nixos" off to my existing workstation, until Claude Code bootstrapped it enough to run on the NixOS machine.
I've been running it as my primary workstation for the last 3-4 weeks, and it's been great! 100% configured by Claude Code or Codex CLI.
Configuring a machine via Nix lang is not that fun. Configuring a machine via English is.
And I've thrown some curveballs at this setup. I asked it for gitbutler-cli, which NixOS doesn't/didn't provide, and it was able to package up and build it. It's running Sway. I have my secrets and configs in SOPS+Home Manager.
I am genuinely confused. Are you saying dotfile managers need to be more complex? Or that nix's problem space is the only solution for the things in nix's domain? (of which dotfiles are just one—via home manager)
I thought it was the former but "just pulling a precompiled, dynamically linked binary and hoping it works" makes me think we're not on the same page since to me that has nothing to do with dotfiles.
I'm saying that I value the completeness (thoroughness may be a better word) as well as the reproducability and portability that nix ensures over convenience. I cant tell you the amount of times I've pulled a precompiled tool and it just doesnt work because of one quirk of their packaging or another.
Also noting that I don't see the problem as "dotfile management" but as "system AND user configuration management" which extends beyond some plain text files in $HOME.
ed.: and home manager is just one tool which provides not only dotfile management, but drvs for installing particular programs and configuring then in highly opinionated ways -- I do not use it
That problem is overstated. I've been dozens of custom packages and modules and it's not that much more complex that basic Nix config, and in fact is a huge positive, not negative. How easy can you write config that packages a binary and/or sets up a new service reproducibly? I'd much rather do that on Nix than Ubuntu or Arch for sure.
Once you hit the Chezmoi stage, you're only about 6 months from Nix and Home Manager. I mean, why climb _almost_ to the top of a mountain and then just sit down?
I ran NixOS for a while, before I switched to Apple Silicon, so I consider myself fairly well-versed-enough (although nowhere near an expert) in Nix and the Nix ecosystem. My last four jobs have all issued me MacBook Pros; the last three with Apple Silicon.
Ultimately, my workplace setup is what has the most gravity. And the most I can get most workplaces to standardize on is Homebrew for package management of off-the-shelf software. Nix is so far outside of the wheelhouse for most engineers that I can't even propose it. It would be too much of a distraction for too many people for too long that it's just not seen as worth it and it's not worth spending the political capital on the attempt. Employers would literally prefer to run scripts from a whitewashing, barely-auditable Jenkins instance with parameterized jobs than to attempt to figure out how to distribute portable scripts and get everyone's permissions working.
So I need to pick software that will cooperate with other tools in an unstable fashion, rather than software that attempts to fully and exclusively control the environment to provide guarantees. Chezmoi fits. Nix and home-manager do not.
You can run Nix and Home Manager on macOS or any Linux distro. You don't even need root.
It works exactly like you describe: it provides its guarantees for all software that you manage through Nix, and doesn't get in the way of software that you don't manage through Nix.
Unlike with NixOS, you can run binaries that expect an FHS-compliant system just fine.
You can just silently use it and enjoy the convenience for the declarative parts of your setup, with no detriment to your ability to run the imperative, ad-hoc setup scripts that your company requires.
I've bounced off Nix every time I tried it, before I even started trying something like Home Manager.
I've been using (and contributing to) chezmoi for ~6 years now. Given that it has first-class integration with secrets managers, I suspect that it does things that Home Manager can't.
I use syncthing to automatically sync my dotfiles git directory across PC/laptops, and stow to manually update symlinks when I add a new dotfile (the content of existing dotfiles is synced by syncthing already)
That way I don't have to remember to commit+push+pull changes to existing dotfiles (like bashrc or vimrc which I edit often) to sync them to other machines, it happens automatically in almost real time as soon as the file is saved on one of my machines (syncthing uses inotify to detect changes on monitored directories)
I've never really understood why people get so fancy with their setups when you can just plop a git repo into your home directory. I suspect it has to do with people being unfamiliar with git.
For me it's useful to have a separate directory with my dotfiles repo, since my dotfiles repo's top level directory doesn't correspond to my home directory. I have one subdirectory for each machine.
It's great to manage your dotfiles, but I took it a step farther. I rebuilt the minimal Linux desktop environment of my dreams (startx, xinit, i3, i3status etc) with Ansible. It begins from a vanilla Ubuntu server 24.04.4 install. I bootstrapped it using a KVM + spice setup (using a spare physical SSD rather than a virtual one) and iterating over and over again until I finally got everything mostly working. I then booted off that physical disk, and kept iterating until everything was perfect. I've since adapted the setup to work on virtual aarch64 on macOS. I just recently tuned it to work on a crappy old Haswell Dell laptop, now properly detecting and configuring hardware vaapi capabilities, backlight, battery, trackpad, trackpoint, etc.
Pretty snazzy, watching YouTube in Firefox on a 13 year old laptop with hardware h264 decode and everything tuned exactly to my liking.
I tried GUIX a few times, but ultimately I couldn't quite get it working exactly the way I wanted it to work. I also didn't like the ugly filesystem layout that the store requires. I may get over it and revisit at some point. It will be a lot of work, but on the plus side I'll have a reason to learn scheme.
Switched to Chezmoi from random assortment of manually authored scripts. The workflow takes some getting used to, because I constantly edit the actual files without calling `chezmoi edit` first, and have to merge.
I like that when combined with `mise` (https://mise.jdx.dev) I can roll out a new computer in 2-3 commands and have my entire environment configured the way I like, with neovim and all the plugins and language servers.
I never did get used to the Chezmoi workflow. `chezmoi edit` never became muscle memory, and I was constant finding myself resolving diffs and what not.
I always like to mention rcm. It's not a popular one but I tried probably 10 managers before it and much prefer it to the competition: https://github.com/thoughtbot/rcm
I looked at Stow and Chezmoi and also have stuck with YADM. The exact reason is that YADM is so simple and intuitive because it's basically Git-for-dotfiles with so little to learn. Yet it also manages to support alternate and template files.
I must've tried to set up stow five or six times over the years, in between various hand rolled custom setups. I can't put my finger on why but I set up chez moi & it's been my setup since, much longer than any previous solution.
Chez moi is definitely not without its rough edges but it seems to have gotten the subtle essentials right enough for adhd me to not have abandoned it yet.
Same here. I would say chezmoi has almost a bit too many features. If one is into yak shaving there is a lot to explore. It's only a negative for me because I forget half of them everytime I read the docs. But I can hardly blame it for that, it's great!
I learned about Stow after I found out about Chezmoi, and felt like Chezmoi was the better fit for me. I make heavy use of templating to keep work / personal aliases and functions separate, and could not be happier with the outcome.
I’ve always managed this problem in a different way. I don’t know if my way is better, but it works really well for me.
I treat my powerful desktop computer as my main machine. Then I have a bunch of laptops.
Then I just rsync my entire home directory out to all the laptops.
From there. The rule is quite simple. Any file created on a laptop are considered ephemeral. If I create data that I have to keep. It gets rsynced back the other direction to the main machine.
This process has served me well for at least 15 years now and is supported by a small handful of shell scripts to automate this process
Interesting. I go about this differently. I have one master setting and from there ruby just autogenerates anything I'd ever need on other computers. If ruby is unavailable then I just copy the generated files. But I only edit the master setting to enable what I need.
> This process has served me well for at least 15 years now and is supported by a small handful of shell scripts to automate this process
I feel in a similar way but not with shell scripts. Ruby autogenerates them if I need them too. Ruby is my ultimate glue to hold together everything.
Chezmoi strikes a nice balance between the overkill of home-manager while still being more powerful than simpler solutions.
Yadm is another alternative, the main thing I don't like about it though is that I'm not a fan of cross OS dotfiles. Having niri files on my work Mac and aerospace dotfiles on Linux annoys me quite a bit.
As powerful as the templating in chezmoi is, I think it should be considered a last resort and only used for simple files. They break your editor features like highlighting.
I hate . dirs. In fact, I hate them so much that I don't use them.
My configuration lives primarily in .yml files. These are kept
super-simple. When need be and another format is required, ruby
autogenerates these for me. For instance, all my bash aliases
are kept in .yml files which then get turned into bash rc files
or any other target format for other shells. Same for most of my
other configuration too - not always .yml but usually some text
file. I never understood the neet for .foobar directories or files.
They just hide a system that is intrinsically ugly and needlessly
complicated.
It’s for things like dotfiles, apt/brew packages, and LaunchAgents/systemd.
EDIT: I feel a little bad having hijacked this, as someone that hears a lot of opinions about devtools I can definitely say chezmoi is a darling of the community and I highly recommend checking it out.
Some months ago I ported part of my git bare repo to chezmoi but never really picked it up since, even if I see it as a great and very complete tool for managing complex dotfiles, I don't have many machines and can live by with a bunch of if uname -s, and the fact that I still need to wrangle brewfiles and scripts for packages. Having the sytem package managers glue along the configs and symlinks is exactly what I wanted.
Being able to centralize this config is far more attractive than having a separate Ansible or pyinfra process.
Hopefully can use this alone instead of needing to combine w/ chezmoi / nix to get everything shell and pkg manager agnostic, consistent, and DRY (bash/zsh/fish + macports/pkgsrc/brew).
The "exception" to that are linux package managers like apt-get and dnf which it calls under the hood. I think can't be an actual issue since it's not like you would ever use ubuntu/redhat without their system package manager installed.
Thanks so much for your work on mise! I used to be a heavy asdf user but nowadays I'm an even heavier mise user!
Random question while you're here: mise is undergoing pretty heavy development these days and I recently noticed that 1) my coworkers and I are not always on the same version, so some features/bug fixes are not available to everyone, and 2) package registries often don't have the latest mise version.
So I think we need a meta tool manager here to manage the tool manager version. :) Seriously, though, have you considered having mise manage its own version? I think that'd be pretty neat!
Thinking aloud, I guess one way to do this might be to distribute through package registries only a lightweight bootstrap application, which 1) reads the pinned mise version from mise.toml and downloads it as necessary, and 2) sets up a basic shell hook that the active mise version can then hook into(?) I know, this probably sounds a lot easier than it actually is.
I would make use of min_version. It's not perfect, but will at least help bring laggards along.
I think Chezmoi's templates and file naming conventions don't click for me, but it's nice to see a good variety in this problem space.
For a System administrator the problem is many orders of magnitude worse
And `home-manager` is maybe the most glaring instance of a tool that is demonstrably ill-posed where the "you're holding it wrong" from the community is a the community problem, not anyone holding anything wrong. From the Zed editor configuration stanza in `home-manager`: https://github.com/nix-community/home-manager/blob/a78606767.... That's not a Zed problem, that's a Nix problem. No one is holding it wrong, XDG config paths get mutated.
Another example and this is the one that really shows the shape of the thing: https://github.com/nixified-ai/flake/blob/bbd3a04fa1ae294096....
There is absolutely nothing "impure" about taking content-addressed bytes from a CAS (Xet in this instance) and surfacing them as a derivation. The "impurity" is called a "coeffect" and the action over the coeffect is called "grade discharge". This is thoroughly studied and works properly, it can cope with all of these cases and it's creates scope for dramatically more reproducible systems that are much easier to reason about (they are possible to reason about). Also, if you can't download shit from HuggingFace in 2026 without a weird hack where the name of the field is a scolding? That's gonna be putting downward pressure on adoption.
And most of the high-friction shit in Nix is like this, ignorance hardened into dogma hardened into theology. To wit:
- FHS vs. zany one-of-a-kind filesystems are nothing to do with purity or hermeticity or reproducibility, it's pure theology and the constant breakage with all the `patchFail` jank is at this point a jobs program, it's totally unnecessary. Namespaces/unshare, we have all the stuff to do this properly (`patchelf` and `unshare --bind-mount` are mathematically dual but only one blows content addressing).
- `drv` hash addressing is a reproducibility war crime. Floating CA is fine it's just broken upstream and in Determinate, it's not a valid ideological debate, it's bugs.
- there is absolutely no reason why the builder where a binary is produced needs to have the same filesystem layout or find libraries in the same place as the resulting artifact runs in any more than an adult needs to live in the same house they grew up in. `patchelf` works.
- having `libcuda.so.1` and friends at `/run/opengl-driver/lib` is dark comedy and source builds of `NCCL` when NVIDIA-certified binaries are in a wheel (zip file) on PyPI is the sequel. this is straight up bad for the planet and we should feel bad we haven't fixed it.
I could go on, but the main point for this thread is to the people who are on the fence about Nix: you're not holding it wrong the `nixpkgs` maintainers are holding it wrong, and more and more of us are getting serious about fixing it. Don't give up on declarative and reproducible systems that you can reason about because Nix is stuck in a weird place as software and as a community. There are reformers on the case.
One major benefit for me is that I no longer need to have once-in-a-while tools installed, because I can always spin up a temporary shell with `nix-shell -p packageName`. This significantly decreased the amount of software I have in my environment.
This works great with agentic coding. Agent wants to run `ripgrep`, but you don't have it? Tell it to run `nix run nixpkgs#ripgrep` instead.
But the biggest benefit is that now that you know Nix! So you can start using it to create reproducible development environments and uninstall mise, asdf, nvm, pyenv, etc. You can spin up reproducible servers running NixOS and never touch Ansible again. You can even install it in your router.
Or you can do none of that and continue just using it for your dotfiles. It plays nice with other tools.
About 6 weeks ago I installed NixOS on a spare laptop and did 100% of the configuration through Claude Codex. Initially I copied "/etc/nixos" off to my existing workstation, until Claude Code bootstrapped it enough to run on the NixOS machine.
I've been running it as my primary workstation for the last 3-4 weeks, and it's been great! 100% configured by Claude Code or Codex CLI.
Configuring a machine via Nix lang is not that fun. Configuring a machine via English is.
And I've thrown some curveballs at this setup. I asked it for gitbutler-cli, which NixOS doesn't/didn't provide, and it was able to package up and build it. It's running Sway. I have my secrets and configs in SOPS+Home Manager.
I like mise, but at the end of the day some programs are more complex than just pulling a precompiled, dynamically linked binary and hoping it works.
I thought it was the former but "just pulling a precompiled, dynamically linked binary and hoping it works" makes me think we're not on the same page since to me that has nothing to do with dotfiles.
Also noting that I don't see the problem as "dotfile management" but as "system AND user configuration management" which extends beyond some plain text files in $HOME.
ed.: and home manager is just one tool which provides not only dotfile management, but drvs for installing particular programs and configuring then in highly opinionated ways -- I do not use it
And in return one gets a saner programming language than the Nix language.
Ultimately, my workplace setup is what has the most gravity. And the most I can get most workplaces to standardize on is Homebrew for package management of off-the-shelf software. Nix is so far outside of the wheelhouse for most engineers that I can't even propose it. It would be too much of a distraction for too many people for too long that it's just not seen as worth it and it's not worth spending the political capital on the attempt. Employers would literally prefer to run scripts from a whitewashing, barely-auditable Jenkins instance with parameterized jobs than to attempt to figure out how to distribute portable scripts and get everyone's permissions working.
So I need to pick software that will cooperate with other tools in an unstable fashion, rather than software that attempts to fully and exclusively control the environment to provide guarantees. Chezmoi fits. Nix and home-manager do not.
You can run Nix and Home Manager on macOS or any Linux distro. You don't even need root.
It works exactly like you describe: it provides its guarantees for all software that you manage through Nix, and doesn't get in the way of software that you don't manage through Nix.
Unlike with NixOS, you can run binaries that expect an FHS-compliant system just fine.
You can just silently use it and enjoy the convenience for the declarative parts of your setup, with no detriment to your ability to run the imperative, ad-hoc setup scripts that your company requires.
I've been using (and contributing to) chezmoi for ~6 years now. Given that it has first-class integration with secrets managers, I suspect that it does things that Home Manager can't.
I did too. Until I tried configuring it with Claude Code. I'll give you my money back guarantee on it.
That way I don't have to remember to commit+push+pull changes to existing dotfiles (like bashrc or vimrc which I edit often) to sync them to other machines, it happens automatically in almost real time as soon as the file is saved on one of my machines (syncthing uses inotify to detect changes on monitored directories)
Pretty snazzy, watching YouTube in Firefox on a 13 year old laptop with hardware h264 decode and everything tuned exactly to my liking.
I like that when combined with `mise` (https://mise.jdx.dev) I can roll out a new computer in 2-3 commands and have my entire environment configured the way I like, with neovim and all the plugins and language servers.
Chez moi is definitely not without its rough edges but it seems to have gotten the subtle essentials right enough for adhd me to not have abandoned it yet.
`make dotfiles` just creates a bunch of symlinks, takes 5 minutes, all good and happy. Everything is modular, declarative, simple. Never looked back.
I treat my powerful desktop computer as my main machine. Then I have a bunch of laptops.
Then I just rsync my entire home directory out to all the laptops.
From there. The rule is quite simple. Any file created on a laptop are considered ephemeral. If I create data that I have to keep. It gets rsynced back the other direction to the main machine.
This process has served me well for at least 15 years now and is supported by a small handful of shell scripts to automate this process
> This process has served me well for at least 15 years now and is supported by a small handful of shell scripts to automate this process
I feel in a similar way but not with shell scripts. Ruby autogenerates them if I need them too. Ruby is my ultimate glue to hold together everything.
stow is an indispensable tool for me to manage /usr/local for manually installed software. my workflow goes:
now, myapp and all its supporting files are in the right place in /usr/local. if i want to "uninstall", i just runYadm is another alternative, the main thing I don't like about it though is that I'm not a fan of cross OS dotfiles. Having niri files on my work Mac and aerospace dotfiles on Linux annoys me quite a bit.
As powerful as the templating in chezmoi is, I think it should be considered a last resort and only used for simple files. They break your editor features like highlighting.
My configuration lives primarily in .yml files. These are kept super-simple. When need be and another format is required, ruby autogenerates these for me. For instance, all my bash aliases are kept in .yml files which then get turned into bash rc files or any other target format for other shells. Same for most of my other configuration too - not always .yml but usually some text file. I never understood the neet for .foobar directories or files. They just hide a system that is intrinsically ugly and needlessly complicated.
‡: https://github.com/b3nj5m1n/xdg-ninja
;)