Rendered at 20:57:08 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
WhyNotHugo 20 hours ago [-]
> The trouble is that symlinks cut both ways. Every edit on every machine writes straight through the link into that machine’s clone of the repo.
I find this is a key feature. If a file is edited, git shows it as dirty, and I get to decide if I discard of commit the change. No extra steps required.
> By the time Homebrew and a couple of tools have run on a new Mac, files like ~/.zprofile and ~/.gitconfig already exist.
I don't get why you'd manually provision those files instead of just putting them in dotfiles.
---
Personally, I found that most tools in this space tried to do too much or were too complex. I previously wrote a minimal one in Rust, but eventually re-wrote it into less than 200 lines of shell, which works pretty much anywhere, without having to install anything at all, and is part of the dotfiles repository itself:
The issue is that you don't really see the git dirty/clean status, because you are rarely/never inside the actual git working tree on your machine. I manage my dotfiles with a simple script that symlinks, and when I go and edit one of those files (through the symlink), I'm either editing from my homedir, or from the directory containing the symlink. When the edit is done, I don't see any git status, because I'm not inside the git repo working tree.
I end up with the same issue as OP: months and months later I'll pop into ~/.dotfiles (where I keep the git repo), and see the tree is dirty, with all these random changes I've made that I don't really remember all that well.
The difference for me vs. the OP is that I consider it a minor inconvenience, spend a few minutes cleaning up and committing, and go about my day. It also helps that I'm pretty much a single-machine guy. I have the dotfiles on random server-like machines in my house, but I basically never edit them on those machines; all edits happen on my laptop, so I never have a problem with conflicts. I could definitely see how this could get annoying for people who edit their dotfiles on several different machines.
duskdozer 15 hours ago [-]
For this, I just added a section to my prompt (bash) showing the state of my dotfiles repo (using yadm). This made sense to me because I'd already done this for a git repo in my current dir. I originally rolled my own but eventually found https://github.com/romkatv/gitstatus which is much faster. So, along with background fetches/pushes, at any point I can tell what revision my dotfiles repo is on and whether it's clean, up to date, conflicted, etc. The time cost for my whole prompt is <20ms.
jdxcode 1 days ago [-]
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.
theshrike79 8 minutes ago [-]
I was just wondering if I could replace my personal Ansible setup with something simpler and now you dropped this.
Perfect timing, I'm already 80% done with the transition :D
0cf8612b2e1e 1 days ago [-]
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.
Edit: The docs on this are very encouraging! However, it is not clear- what is experimental? Anything notably buggy or churning? Any far off features you hope to implement some day?
jdxcode 24 hours ago [-]
ALL mise features are experimental until the design is finalized. I don’t do breaking changes except in exceptional circumstances with a long procedure, so experimental means I have the liberty of making them in any release. It is not at all any marker of quality. That said, in practice I don’t make them often.
I’d argue it’s a good time to play with features since if you have any ideas on how it might better fit your workflow I still have the ability to change the design before it’s largely frozen.
throawayonthe 1 days ago [-]
i would reach for atomic fedora personally, maybe with bluebuild
0cf8612b2e1e 1 days ago [-]
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.
sharts 1 days ago [-]
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).
jdxcode 1 days ago [-]
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.
frangonf 1 days ago [-]
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.
halostatue 1 days ago [-]
Are there plans to support MacPorts as a packaging system? I only use Homebrew for casks, because I find it unreliable for core development tools.
jdxcode 1 days ago [-]
Haven't looked into it but agents are so good at this I bet it'll be trivial to add
codethief 1 days ago [-]
Ha, I came here to share this! :)
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.
jdxcode 1 days ago [-]
The problem with mise managing its own version is perf. I don't want a shim that has to read config files to exec the right version.
I would make use of min_version. It's not perfect, but will at least help bring laggards along.
drdexebtjl 1 days ago [-]
I had similar problems with GNU Stow, but switched to Nix and Home Manager instead.
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.
bkummel 1 days ago [-]
I didn't even know that managing dotfiles was a "problem space".
kstrauser 1 days ago [-]
It's dead simple to manage files in git or such. What Chezmoi adds over that are niceties like:
* Permission management, so that ssh wouldn't refuse to log you in because ~/.ssh/authorized_keys is 0755 instead of 0644.
* Templating, because ~/.ssh/config has slightly different options on Mac and Linux, so you can't use the exact same file contents as-is on both systems.
I can run `chezmoi apply` and get all the files in the right places and they're all setup just right. Like so many others, I'd previously built my own ad-hoc system to handle these things, and it ended up looking like a crappy, half-baked version of Chezmoi. When it came up on my radar I immediately ported my own system over to it and never looked back.
theshrike79 2 hours ago [-]
Also encryption with `age`.
My ssh config has actual domain names of servers I don't want to publish to the whole internet so that file is encrypted on my public github dotfiles repo.
Chezmoi automatically decrypts it on `chezmoi update` and I don't need to think about it much unless I'm editing it.
kstrauser 1 hours ago [-]
Oh, that's slick. I haven't needed to do that yet and I keep my stuff in a private repo, but see the benefits to it.
awesome_dude 1 days ago [-]
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
colordrops 1 days ago [-]
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.
drdexebtjl 1 days ago [-]
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.
QwenGlazer9000 1 days ago [-]
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.
linsomniac 1 days ago [-]
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.
jorvi 1 days ago [-]
Nix's complexity isn't with itself, its if you try to step one bit off the beaten path where it immediately starts to grate.
colordrops 1 days ago [-]
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.
jolmg 20 hours ago [-]
If you modify a base package, like maybe to apply some minor patch on a systemd executable as an example, is there a way to avoid having to recompile basically all installed packages (for being at least indirect dependents)? Had a problem like that about a decade back.
colordrops 18 hours ago [-]
No, it doesn't recompile everything, that's not how Nix works. The only way it would recompile everything is if, for example, you modified a particular version of glibc that was imported by most packages. Something else must have happened. I modify udev rules and the system rebuilds in seconds.
That's the great thing about nix, it should actually compile LESS than other distros, because, you can have multiple versions of the same lib on the same machine. You just create another version of the package and only patch the packages that need it. You don't even have this option on other distros. Name one other distro that lets you run multiple versions of glibc natively (not containers or flatpaks or whatever).
jolmg 18 hours ago [-]
> The only way it would recompile everything is if, for example, you modified a particular version of glibc that was imported by most packages.
The package dependencies aren't based on whether what's packaged is a linked library, and built packages are linked to the dependencies by the digests. The digest of a package is made from the store derivation which contains the digests of the dependencies. Or does the digest of a package not depend on the digests of its dependencies anymore?
Because if they do, then on changing any minor thing, like a typo on a manpage, it would cause the change to cascade by changing the digests of its own package and its dependants recursively. Meaning, none would be found prebuilt and would need to be recompiled.
EDIT: s/hashes/digests/ because that's what appears to be the conventional name for the base32 strings used to identify an entry in /nix/store. The site has changed a lot in the last decade, but I do see this in the thesis that confirms what I remembered:
> The store derivation in /nix/store/1ja1w63wbk5q...-hello-2.1.1.drv is shown in Figure 2.13. It lists all information necessary to build the component, with references to the store derivations of dependencies [...] The output field specifies the path that will be built by this derivation, if and when it is built. It is computed essentially by hashing the store derivation with the output field cleared. --- https://edolstra.github.io/pubs/phd-thesis.pdf
EDIT 2:
> I modify udev rules and the system rebuilds in seconds.
Maybe there's a beaten path for udev rules, a way to override them without modifying the package / store derivation. Or maybe the derivations you're modifying don't have many dependants.
colordrops 14 hours ago [-]
I didn't say anything about linked libraries. I was just using glibc as an example. I could have used a man page too.
4 hours ago [-]
3 hours ago [-]
chungy 1 days ago [-]
Guix solves the same problem in similar ways, though it uses Scheme as its configuration language.
drdexebtjl 1 days ago [-]
Sadly it doesn't work on macOS, unlike Nix.
pkulak 1 days ago [-]
Or hardware.
sham1 1 days ago [-]
It absolutely works with hardware. And it's not that difficult to add channels for extra software like a tainted Linux kernel.
And in return one gets a saner programming language than the Nix language.
jdxcode 1 days ago [-]
how nix-pilled do you have to be to think that nix is the "only real solution" to dotfile managers?
tfrancisl 1 days ago [-]
Its the only complete, reproducible, and portable solution, in my opinion.
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.
jdxcode 1 days ago [-]
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.
tfrancisl 1 days ago [-]
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
bronson 1 days ago [-]
> I can't 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.
This is a serious problem in Nix too. I often trip over buggy and abandoned Nix packages. Nix often makes it easy to roll back or work around them, but they're absolutely there.
colordrops 23 hours ago [-]
They still build though. No one said anything about Nix being a solution to buggy software or bad maintainers, that's an absurd expectation.
drdexebtjl 23 hours ago [-]
I don't think you're genuinely confused.
Are you really in this thread to talk about dotfile managers, or are you here to criticize Nix, given that Nix directly competes with your company's only product?
jdxcode 23 hours ago [-]
Considering nothing in that reply criticized nix you’re certainly wrong. I don’t hesitate to share my opinions on nix anytime (just like nix users themselves) so I’d have no reason to be coy about my criticism.
tfrancisl was polite (even though I arguably wasn’t in the beginning) so I felt it important to return the favor.
colordrops 1 days ago [-]
"real" meaning truly reproducible and not brittle.
arikrahman 22 hours ago [-]
A agree, Nix is very doable. With Deepseek or other cheaper models, you could get a whole headache-free setup done in one weekend for a few cents on the dollar.
NamlchakKhandro 21 hours ago [-]
Nix doesn't work on windows.
It's also a massive pain the ass to work with
tfrancisl 1 days ago [-]
If you like home manager but also like to understand how your "home"/user programs are configured, take a look at hjem!
drdexebtjl 1 days ago [-]
Last time I looked, it only worked with NixOS.
I don't understand what makes it more understandable than Home Manager, though.
If you look at the source of a Home Manager `programs.foo` module, it should look mostly like this:
Which is pretty much exactly the same syntax you get with Hjem, but with more optional features. So you could just write that instead whenever you want full control :)
tfrancisl 24 hours ago [-]
It works on darwin and any linux just fine. Theyre even working on a "standalone" like HMs, if you really want to decouple your user programs from your system.
With some programs it is as simple as you show, but with others there are options around the config and other nix module nasties that I avoid if I can. hjem-rum is a sister project to hjem that provides some similar modules.
drdexebtjl 23 hours ago [-]
I'll take a look again once it's a bit more mature. I need a standalone, single-user, rootless mode for it to work on all my systems.
Thanks for the recommendation.
reinitctxoffset 1 days ago [-]
[flagged]
tfrancisl 1 days ago [-]
What a snakepit of a comment! I know there are tensions within nix but this feels like a classic case of Chestertons fence at a big scale.
charcircuit 1 days ago [-]
These things really do not have an actual reason. Take for example the Nic people who go to every project with a bash script that uses #!/bin/bash and tells them to use #!/usr/bin/env bash. There is no justification for trying to fix every bash script in existence over the operating system being able to resolve what the "current" bash version should be (/usr/bin/env already has to pick a version). This is pointless O(n) busy work Nix people have created for themselves when an O(1) solution exists.
zaik 6 hours ago [-]
If you decide to create a package for the project in nixpkgs, patch-shebangs.sh should do it for you, no?
reinitctxoffset 2 hours ago [-]
Getting a patch into `nixpkgs` is not a reasonable bar for running some program you want to try. This is an (admittedly polite) way of saying more or less "you're holding it wrong". I respectfully disagree.
For expert users, creating a flake and/or standalone derivation is a little more reasonable of an ask. It is an unreasonable ask of people who are considering adopting Nix, and the friction is artificial, it serves no practical benefit (you'll notice that things like `nix-ld` are in `nix-community` now, long-time community contributors like Mic92 said a long time ago, we need to stop the bleeding on this).
And once you get out of the merely alienating to anyone used to being treated well, and into actually complex software builds, "possible once you learn the incantations" goes to "never happens, you will never run this without Docker on NixOS".
I won't settle for that, so I fix things:
```
b7r6 on ultraviolence ~
nix run github:sensenet-ai/nvidia-sdk#python
Python 3.12.12 (main, Oct 9 2025, 11:07:00) [GCC 15.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorrt_llm
W0619 15:07:35.110000 14798 /nix/store/xgk8wcis2avy1vsv66viw150jv78v6qs-ngc-python-packages-ngc-25.12-rootfs/lib/python3.12/site-packages/torch/utils/cpp_extension.py:2422] TORCH_CUDA_ARCH_LIST is not set, all archs for visible cards are included for compilation.
W0619 15:07:35.110000 14798 /nix/store/xgk8wcis2avy1vsv66viw150jv78v6qs-ngc-python-packages-ngc-25.12-rootfs/lib/python3.12/site-packages/torch/utils/cpp_extension.py:2422] If this is not desired, please set os.environ['TORCH_CUDA_ARCH_LIST'] to specific architectures.
[TensorRT-LLM] TensorRT LLM version: 1.1.0
>>> import torch
>>> torch.cuda.is_available()
True
>>>
```
reinitctxoffset 1 days ago [-]
[dead]
marshray 1 days ago [-]
Mommy, the Nix Reformationist is scaring me
drdexebtjl 24 hours ago [-]
Worse is better.
reinitctxoffset 21 hours ago [-]
Gabriel, who is a legend, was very bitter when he wrote that. A lot of people took the death of Lisp in industry very hard and he had more skin in the game than most.
Worse is not better any more than a tough man stops short of a tender chicken. Better is better.
Your second example i dont understand what you're getting at.
This is just a mechanism for the builder to inject credentials during fetch time. The derivation is still content addressed (it's a fixed output derivation).
The derivation isn't even marked as impure or whatever. There is just an environment variable that gets injected by the builder into the build env so you can authenticate.
This is required to talk to hugging face
What are you on about?
Or do you mean that the cas address of HF should directly be addreessable in nix itself?
reinitctxoffset 21 hours ago [-]
I understand in considerable detail what's happening here, having written a conforming implementation of `nix` myself.
Silently smuggling environment variables into a builder means the build is not reproducible, nor is it possible to know a-priori whether the build is reproducible. Nix reverts to the same level of guarantee you get from Ubuntu or whatever without the convenience of Ubuntu: Docker is dramatically more principled!
The galaxy brain people who do real mathematics of whom I am merely a humble fan worked this one out. The credential is a "coffect", which is a generalization of this sort of thing that is tracked ("graded") and accounted for ("discharged"), a process that allows you to reason about your system (to for example know that a massive build is going to be useless before you do it since you don't have the credential for the model you were trying to run with the thing you built).
Punching random holes in Nix is worse than just disabling the sandbox or whatever other BDSM thing, because if you aren't going to get correct you might as well get easy.
Why put up with Nix's bullshit if it's still going to be less correct than Docker anyways? Most people agree (c.f. Docker as opposed to Nix winning too hard in the market).
My approach is different: unfuck Nix.
arianvanp 11 hours ago [-]
Euhm what the hell are you on about. This is a fixed output derivation. The output per definition is reproducible. It either returns a value that matches the hash or it fails.
The whole point is that it allows introducing controlled side effects as long as the output is reproducible.
Bur you're extremely annoying to talk to so I'm not gonna continue engaging. Probably an LLM
reinitctxoffset 3 hours ago [-]
The outcome isn't even reproducible if GitHub is down, so like multiple times a week now. And FODs routinely break because of the dozens of leakage modes in the evaluation cache (if flakes are involved), the dozens of races (mostly TOCTOU or adjacent) on the `sqlite` interface and other store-adjacent bugs (`ssh-ng` is especially broken, that's actually the biggest blocker to floating CA at the moment), and so it is very easy to change the declared hash of a fixed-output derivation (for example, you're iterating on the upstream artifact) and have an old one stuck in cache/store because the `Aterm` driving the NAR calculation doesn't trip a fetcher invoke.
This stuff doesn't work, and mixing in ambient environment state is the cross product of the current amount of broken with now it's not even the same on my laptop and desktop.
If you know of an LLM that understands this stuff in this kind of detail, I would be in your debt for a referral, because I sure as hell wish I didn't have to know all this stuff.
And if it's annoying to make vague claims without supporting evidence and have them refuted by concrete arguments with specific details cited than HN may not be the place for you. Being right matters here. I haven't been rude, or made it personal (vis-a-vis "you're extremely annoying" which I don't appreciate).
I don't get the personal attack on this. I'm talking facts about technology.
pkulak 1 days ago [-]
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?
halostatue 1 days ago [-]
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.
linsomniac 1 days ago [-]
>I've bounced off Nix every time I tried it, before I even started trying something like Home Manager.
I did too. Until I tried configuring it with Claude Code. I'll give you my money back guarantee on it.
bronson 1 days ago [-]
Vibed infrastructure? That sounds like it undoes a lot of Nix's advantages.
redog 17 hours ago [-]
> it has first-class integration with secrets managers
Meow?
halostatue 7 hours ago [-]
No slight involved.
The chezmoi integration with 1Password is excellent; for those who prefer Bitwarden, it supports both the default CLI (which has some inexcusable behaviours for a security product, IMO) and `rbw` (which is infinitely better than the default CLI). It supports `pass`, `gopass`, `passage`, AWS Secrets Manager, KeePass, and several other approaches.
It was the work of a couple of minutes to enable a secret for a Claude Code API token to be mounted in a VM where I'm running Claude for a project where the value is pulled from 1Password and I can regenerate it and reapply without fear.
If one doesn't have to worry about secrets in one's dotfiles, I'm sure that other dotfile managers including Nix with Home Manager will suffice. I do, so they won't.
solatic 1 days ago [-]
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.
drdexebtjl 1 days ago [-]
So don't propose it?
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.
solatic 12 hours ago [-]
> 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.
That's the kicker though. Nix's benefits come from the guarantees it can make based on its integration with the rest of the Nix-controlled ecosystem. Without the control, you don't get the guarantees, and you lose the raison d'être. You need to actively avoid the "value-added" parts (e.g. package options) because latest Homebrew upstream may give you a version that exposes an option that is not yet exposed by the package options, and you can't patch the package with Nix because you're not using a Nix-based package.
Chezmoi is declarative. The templates give me generated configuration. I can rollback anytime I want by reverting Git commits and calling chezmoi apply. It works well within its less-ambitious goals (compared to Nix).
drdexebtjl 7 hours ago [-]
If you’re using Nix and HM to manage a configuration file for a package that isn’t managed by Nix and HM, you don’t get the same guarantees, sure.
But you also don’t get them at all with Chezmoi, right?
Surely having these guarantees for some packages beats having it for none? In practice _most_ packages you’ll want to use are already in Nixpkgs, and kept up to date.
> You need to actively avoid the "value-added" parts (e.g. package options) because latest Homebrew upstream may give you a version that exposes an option that is not yet exposed by the package options, and you can't patch the package with Nix because you're not using a Nix-based package.
You mean build-time options?
You can usually override the version number/URL in your own configuration to get the new version earlier. But new versions land in nixpkgs-unstable with about the same cadence as Homebrew anyway.
Same thing with runtime options. Want `programs.foo.enableNewThing` but it’s not in HM yet? You can just define that option in your own configuration, no need to stop using the value-added module nor wait for HM.
17 hours ago [-]
tfrancisl 1 days ago [-]
Or nix without home manager, and ideally without flakes as well. Two solutions looking for problems, IME.
NamlchakKhandro 20 hours ago [-]
Because nix is over complicated and doesn't work on windows
senotrusov 19 hours ago [-]
I evaluated most of the popular dotfile management tools and found them far too complex for the problems they try to solve. I then used stow for about a year just to see whether symlinks would cause any issues. They did.
Eventually, I wrote my own bidirectional sync tool that synchronizes a git checkout (for example, ~/.dotfiles) with the actual home directory. I run it as a systemd service, so I can simply edit or delete files in ~/.dotfiles, and everything else happens automatically.
I can add or remove files in the repository, and they will automatically be created or removed in their synchronized locations. At the same time, the target directories can contain other unrelated files, including an entire $HOME, and this does not interfere with synchronization in any way.
The bidirectional sync is particularly useful when a program, such as vs code, decides to modify its own configuration files, or when I'm feeling lazy and just want to edit ~/.bashrc directly and commit the changes later.
Achieving this requires some careful logic that, hopefully, I've managed to get right. At least at the time I wrote it, I hadn't seen these implemented in other systems.
Oh, and I use the same sync for some files I need to /etc, only for that I run sudo scripts and dont' have a always-on service for obvious reasons.
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.
1 days ago [-]
LVB 1 days ago [-]
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.
vsviridov 22 hours ago [-]
BeyondCompare 2-way merge usually resolves everything automatically, and it's set up as the default mergetool for me, so it's only a couple of clicks... But yeah, takes some muscle memory.
ceving 8 hours ago [-]
I don't understand why anyone would bother doing something like Stow. I keep my home directory directly in a Git repository that ignores all files by default, and for systems with specific configurations, I simply create a branch.
theshrike79 2 hours ago [-]
But if you have 6-10 machines you use and they're all a bit different, doesn't the branching get a bit tedious when you want to edit something that's common for all?
Vs. the chezmoi way of keeping everything common except using templates for diverging files.
rochak 1 days ago [-]
I've been using [yadm](https://yadm.io/) instead which works really well!
jdxcode 1 days ago [-]
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
laurentlbm 1 days ago [-]
I've been happy with yadm for few years now. I had tried chezmoi, but preferred yadm. I don't remember my exact reasons though...
markstos 1 days ago [-]
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.
duskdozer 15 hours ago [-]
I looked around at a bunch but settled on yadm for basically just using a normal git workflow. I wanted to just edit the files directly, know what it's doing, and not change how I worked. I really dislike the `<tool> edit/run/<standard command>` UI pattern that's fairly common now.
spudlyo 1 days ago [-]
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.
trallnag 1 hours ago [-]
I did that too across three devices and it turned out to be a huge time sink similar to tinkering with a personal server
anuramat 1 days ago [-]
don't want to be that guy, but have you tried nix?
spudlyo 1 days ago [-]
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.
lucideer 1 days ago [-]
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.
guhcampos 1 days ago [-]
I used stow for a long time, then tried Ansible, but eventually settled into good old Make.
`make dotfiles` just creates a bunch of symlinks, takes 5 minutes, all good and happy. Everything is modular, declarative, simple. Never looked back.
lucideer 9 hours ago [-]
I think this is likely a part of the friction for a lot of people - symlinks.
There's roughly two main ways to manage dotfiles:
- symlink
- copy & sync
The 2nd (what chez moi does) is pretty hard to get right from a UX perspective.
sureglymop 1 days ago [-]
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!
linhns 1 days ago [-]
I nearly jumped from GNU Stow, but settled when I find the —-no-folding flag
blop 1 days ago [-]
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)
c-hendricks 22 hours ago [-]
This is what I did too. My dotfiles used a custom install process that didn't really handle ~/.config very well, so I switched to stow, and then added syncthing because the push + pull dance got too annoying. Really happy with it.
gchamonlive 24 hours ago [-]
> The trouble is that symlinks cut both ways. Every edit on every machine writes straight through the link into that machine’s clone of the repo
I have stow too in my micro DE, use it across a few machines and it's holding up really well. I designed my dotfiles so that changes would happens exclusively to files not tracked by stow. I have .zshrc tracked, but environment goes to .zshenv and general local customisation goes to .local/lib/zsh/overrides.zsh (https://gitlab.com/gabriel.chamon/archie/-/blob/main/deploym...). Hyprland config is tracked but device specific configs live in .config/hype/config/device.conf (https://gitlab.com/gabriel.chamon/archie/-/blob/main/deploym...). Deployment instructions/automation is to just copy dist folders in place, which aren't tracked by stow.
It depends on everyone's style. For me personally changes I don't remember having made to files I track in the repo are symptoms that I might need to review how I organize my files. Maybe those changes were something that broke and I forgot to commit after fixing. In any case for me this bidirectional nature of symlinks are a feature, not a bug in this management system.
technojamin 23 hours ago [-]
I've checked out stow, chezmoi, yadm, and others over the years, but I originally started off by rolling my own dotfiles setup with a Git repo about 6 years ago: https://github.com/jaminthorns/environment
I don't really recommend it to others, since there's all these great tools that have the features you need (per-machine config, secrets, templating), but I get a deep satisfaction from the fact that I understand every part of this setup from top to bottom. It only has the functionality I need, and I know it doesn't depend on anything that might become unmaintained since it's just POSIX shell scripts.
Even still, I might eventually make the jump to something like chezmoi or nix if I'm not able to implement something I need easily, but that hasn't happened yet.
nickjj 22 hours ago [-]
> don't really recommend it to others, since there's all these great tools that have the features you need
I thought about using any one of those tools but happily chose shell scripts and symlinks instead. It hasn't let me down in almost a decade with https://github.com/nickjj/dotfriedrice and would highly recommend this approach.
It's basically a 2,500 line shell script to fully automate setting up a system from scratch in a general purpose / opinionated but customizable way that works on Arch Linux, Debian, Ubuntu, macOS and supports WSL 2 in Windows. I have it running on multiple systems, no need to even fork it since it uses patterns suitable for making changes in git ignored files and also has a config file for certain things.
When it comes to setting up a complete desktop environment or even just terminal based tools, dotfiles IMO are more than config files. There's install scripts, packages, system level configs, running commands, OS specific differences and more. It's really nice to be able to run 1 command and have a fresh system ready to go in about 10 minutes.
Shell script is probably my favorite language at this point.
nsagent 21 hours ago [-]
I moved from custom POSIX shell scripts to chezmoi due to the complexity of handling lots of random environments. It really simplified getting up and running on disparate server environments.
The last few years I've rarely had to switch machines, so maybe chezmoi is overkill now, but it works well, so I'm in no rush to simplify again just for the sake of it (and who knows if I'll need chezmoi's features for real again in the future).
ivanjermakov 22 hours ago [-]
Same, I wrote a simple program reading master file and copying dotfiles according to "recipes" in it.
mmh0000 1 days ago [-]
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
cwel 23 hours ago [-]
> rsync my entire home directory out to all the laptops
Interesting approach. Whether it could be considered 'better' or not depends on what your 'handful of shell scripts' do.
mixmastamyk 16 hours ago [-]
I feel like git or other vcs would be a bit safer. I could see myself syncing the wrong way.
1 days ago [-]
shevy-java 1 days ago [-]
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.
TeriyakiBomb 23 hours ago [-]
I found chezmoi kind of annoying and then just moved to symlinks and a fossil repo. Low tech and low drama
darkteflon 24 hours ago [-]
Ok, I came into this thread intending to say “I’ve been using stow for years and am perfectly happy with it”, started RTFA and the comments, realised that I was actually not happy with it, started considering chezmoi then remembered that I had had a pretty great experience building a Nix VM recently.
Now I want to use Nix* to manage my multi-machine MacOS and Linux setup (with lots of dotfile config overlap, of course).
That’s the HN experience for you.
Kind souls: what is currently the blessed way to manage MacOS dots with Nix? I recall there is more than one paradigm - what’s the approach that simplest, most robust and can be adopted incrementally?
Edit: Just to say that I think Atuin now also plays in this space. Haven’t checked it out, though.
theshrike79 11 minutes ago [-]
The saying used to be "every application extends until it can read email"
Now it should be "every app adds features until it manages dotfiles" :D
Dunno why I'd use atuin for dotfile management, but some people seem to like it. It's very good at syncing and managing shell history though.
This one is good, though, and very thorough—even though it's Mac-centric.
Ferret7446 1 days ago [-]
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.
uasi 1 days ago [-]
Git works until you need conditional logic such as platform-specific files or templating.
mixmastamyk 16 hours ago [-]
I'm multi-platform and use git. A few scripts include things like this, but for the most part are portable.
# fish
if set -q TERM_PROGRAM # mac os
...
else if test "$COLORTERM" = "kmscon"
...
else # tron leotards
...
end
# bash
if test "$WAYLAND_DISPLAY" == ""; then
echo X11
else
echo Found Wayland
fi
if test -e /etc/fedora-release; then
echo ...
else
# Debian
fi
Ferret7446 19 hours ago [-]
There are various options:
You can make forks or branches. Perfect for separating your work specific or private configs
You can use a shell script (stored in the same git repo). You need you run an external tool with dotfile managers anyway, a shell script gives you more flexibility and doesn't need an extra dependency which might break at an inopportune time. The last thing you need is your dotfile manager breaking when you're setting up a new machine (ask me how I know)
uasi 17 hours ago [-]
You can, but forks or branches need constant merging or rebasing (and sometimes conflict resolution) for each one. Clean/smudge filters are fiddly to set up correctly and almost certainly require shelling out to another program, which could break. The second-to-last thing you need is your hand-rolled solution breaking on a new environment. If and when you need several advanced features that a stable dotfiles manager already covers, why roll your own?
MarsIronPI 1 days ago [-]
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.
1 days ago [-]
arrakeen 1 days ago [-]
i feel like using GNU stow to manage your dotfiles has always been a hack.. has it ever been a supported usecase?
stow is an indispensable tool for me to manage /usr/local for manually installed software. my workflow goes:
./configure --prefix=/usr/local/stow/myapp
make && make install
stow myapp
now, myapp and all its supporting files are in the right place in /usr/local. if i want to "uninstall", i just run
stow -D myapp
WCSTombs 23 hours ago [-]
I like to use environment modules [1] (or lmod [2]) for that purpose. You can make each manually built software package available or not on a per-shell-session basis, just by running
module load myapp
or
module unload myapp
in the shell where you want it (or don't). The small downside is that it only works with software that actually uses the standard environment variables like PATH, CPATH, etc. for their intended purposes rather than hardcoding filesystem paths, but in my experience it's rare to find something that doesn't. Also, you have to write a modulefile for each package, but that's not a big deal.
~50 years of distributed systems research and this is a problem we still have to deal with today. Sad!
sgarland 1 days ago [-]
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.
QwenGlazer9000 1 days ago [-]
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.
cwel 23 hours ago [-]
> Having niri files on my work Mac and aerospace dotfiles on Linux annoys me quite a bit
What was your inspiration for writing this? / What bloat did you shed relative to chezmoi?
taegee 15 hours ago [-]
I just ditched Chezmoi in favor of GNU Stow …
cocodill 22 hours ago [-]
Someone needs to tell this dude about the git branches.
mmmmbbbhb 15 hours ago [-]
Honestly, I think you'd benefit from vibe coding your own solution. That way it fits you like a glove.
globular-toast 13 hours ago [-]
The only thing currently annoying me with my Stow setup is handling machine-specific changes. I have a "work" branch in my repo that I have to keep rebased on my master branch. Weird things happen if that rebase causes conflicts in the git config! It's also just annoying.
Does Chezmoi have a better solution for that? Or is there a better way using Stow?
theshrike79 9 minutes ago [-]
With chezmoi you'd create templates from the config files, which would apply/ignore specific bits depending on whatever selector you want (machine name, OS etc)
shevy-java 1 days ago [-]
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.
RunningDroid 1 days ago [-]
You might like xdg-ninja‡ then, it tells you what program put which item in your $HOME and how to move it to ~/.config or $XDG_CONFIG_HOME.
I find this is a key feature. If a file is edited, git shows it as dirty, and I get to decide if I discard of commit the change. No extra steps required.
> By the time Homebrew and a couple of tools have run on a new Mac, files like ~/.zprofile and ~/.gitconfig already exist.
I don't get why you'd manually provision those files instead of just putting them in dotfiles.
---
Personally, I found that most tools in this space tried to do too much or were too complex. I previously wrote a minimal one in Rust, but eventually re-wrote it into less than 200 lines of shell, which works pretty much anywhere, without having to install anything at all, and is part of the dotfiles repository itself:
https://git.sr.ht/~whynothugo/dotfiles/tree/ac97cb196f02cafa...
I end up with the same issue as OP: months and months later I'll pop into ~/.dotfiles (where I keep the git repo), and see the tree is dirty, with all these random changes I've made that I don't really remember all that well.
The difference for me vs. the OP is that I consider it a minor inconvenience, spend a few minutes cleaning up and committing, and go about my day. It also helps that I'm pretty much a single-machine guy. I have the dotfiles on random server-like machines in my house, but I basically never edit them on those machines; all edits happen on my laptop, so I never have a problem with conflicts. I could definitely see how this could get annoying for people who edit their dotfiles on several different machines.
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.
Perfect timing, I'm already 80% done with the transition :D
Being able to centralize this config is far more attractive than having a separate Ansible or pyinfra process.
Edit: The docs on this are very encouraging! However, it is not clear- what is experimental? Anything notably buggy or churning? Any far off features you hope to implement some day?
I’d argue it’s a good time to play with features since if you have any ideas on how it might better fit your workflow I still have the ability to change the design before it’s largely frozen.
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.
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.
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.
* Permission management, so that ssh wouldn't refuse to log you in because ~/.ssh/authorized_keys is 0755 instead of 0644.
* Templating, because ~/.ssh/config has slightly different options on Mac and Linux, so you can't use the exact same file contents as-is on both systems.
I can run `chezmoi apply` and get all the files in the right places and they're all setup just right. Like so many others, I'd previously built my own ad-hoc system to handle these things, and it ended up looking like a crappy, half-baked version of Chezmoi. When it came up on my radar I immediately ported my own system over to it and never looked back.
My ssh config has actual domain names of servers I don't want to publish to the whole internet so that file is encrypted on my public github dotfiles repo.
Chezmoi automatically decrypts it on `chezmoi update` and I don't need to think about it much unless I'm editing it.
For a System administrator the problem is many orders of magnitude worse
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.
That's the great thing about nix, it should actually compile LESS than other distros, because, you can have multiple versions of the same lib on the same machine. You just create another version of the package and only patch the packages that need it. You don't even have this option on other distros. Name one other distro that lets you run multiple versions of glibc natively (not containers or flatpaks or whatever).
The package dependencies aren't based on whether what's packaged is a linked library, and built packages are linked to the dependencies by the digests. The digest of a package is made from the store derivation which contains the digests of the dependencies. Or does the digest of a package not depend on the digests of its dependencies anymore?
Because if they do, then on changing any minor thing, like a typo on a manpage, it would cause the change to cascade by changing the digests of its own package and its dependants recursively. Meaning, none would be found prebuilt and would need to be recompiled.
EDIT: s/hashes/digests/ because that's what appears to be the conventional name for the base32 strings used to identify an entry in /nix/store. The site has changed a lot in the last decade, but I do see this in the thesis that confirms what I remembered:
> The store derivation in /nix/store/1ja1w63wbk5q...-hello-2.1.1.drv is shown in Figure 2.13. It lists all information necessary to build the component, with references to the store derivations of dependencies [...] The output field specifies the path that will be built by this derivation, if and when it is built. It is computed essentially by hashing the store derivation with the output field cleared. --- https://edolstra.github.io/pubs/phd-thesis.pdf
EDIT 2:
> I modify udev rules and the system rebuilds in seconds.
Maybe there's a beaten path for udev rules, a way to override them without modifying the package / store derivation. Or maybe the derivations you're modifying don't have many dependants.
And in return one gets a saner programming language than the Nix language.
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
This is a serious problem in Nix too. I often trip over buggy and abandoned Nix packages. Nix often makes it easy to roll back or work around them, but they're absolutely there.
Are you really in this thread to talk about dotfile managers, or are you here to criticize Nix, given that Nix directly competes with your company's only product?
tfrancisl was polite (even though I arguably wasn’t in the beginning) so I felt it important to return the favor.
It's also a massive pain the ass to work with
I don't understand what makes it more understandable than Home Manager, though.
If you look at the source of a Home Manager `programs.foo` module, it should look mostly like this:
Which is pretty much exactly the same syntax you get with Hjem, but with more optional features. So you could just write that instead whenever you want full control :)With some programs it is as simple as you show, but with others there are options around the config and other nix module nasties that I avoid if I can. hjem-rum is a sister project to hjem that provides some similar modules.
Thanks for the recommendation.
For expert users, creating a flake and/or standalone derivation is a little more reasonable of an ask. It is an unreasonable ask of people who are considering adopting Nix, and the friction is artificial, it serves no practical benefit (you'll notice that things like `nix-ld` are in `nix-community` now, long-time community contributors like Mic92 said a long time ago, we need to stop the bleeding on this).
And once you get out of the merely alienating to anyone used to being treated well, and into actually complex software builds, "possible once you learn the incantations" goes to "never happens, you will never run this without Docker on NixOS".
I won't settle for that, so I fix things:
``` b7r6 on ultraviolence ~ nix run github:sensenet-ai/nvidia-sdk#python Python 3.12.12 (main, Oct 9 2025, 11:07:00) [GCC 15.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import tensorrt_llm W0619 15:07:35.110000 14798 /nix/store/xgk8wcis2avy1vsv66viw150jv78v6qs-ngc-python-packages-ngc-25.12-rootfs/lib/python3.12/site-packages/torch/utils/cpp_extension.py:2422] TORCH_CUDA_ARCH_LIST is not set, all archs for visible cards are included for compilation. W0619 15:07:35.110000 14798 /nix/store/xgk8wcis2avy1vsv66viw150jv78v6qs-ngc-python-packages-ngc-25.12-rootfs/lib/python3.12/site-packages/torch/utils/cpp_extension.py:2422] If this is not desired, please set os.environ['TORCH_CUDA_ARCH_LIST'] to specific architectures. [TensorRT-LLM] TensorRT LLM version: 1.1.0 >>> import torch >>> torch.cuda.is_available() True >>> ```
Worse is not better any more than a tough man stops short of a tender chicken. Better is better.
https://gist.github.com/b7r6/57b9057b87a56e98c4d306d83eed5dc...
This is just a mechanism for the builder to inject credentials during fetch time. The derivation is still content addressed (it's a fixed output derivation).
The derivation isn't even marked as impure or whatever. There is just an environment variable that gets injected by the builder into the build env so you can authenticate.
This is required to talk to hugging face
What are you on about?
Or do you mean that the cas address of HF should directly be addreessable in nix itself?
Silently smuggling environment variables into a builder means the build is not reproducible, nor is it possible to know a-priori whether the build is reproducible. Nix reverts to the same level of guarantee you get from Ubuntu or whatever without the convenience of Ubuntu: Docker is dramatically more principled!
The galaxy brain people who do real mathematics of whom I am merely a humble fan worked this one out. The credential is a "coffect", which is a generalization of this sort of thing that is tracked ("graded") and accounted for ("discharged"), a process that allows you to reason about your system (to for example know that a massive build is going to be useless before you do it since you don't have the credential for the model you were trying to run with the thing you built).
Punching random holes in Nix is worse than just disabling the sandbox or whatever other BDSM thing, because if you aren't going to get correct you might as well get easy.
Why put up with Nix's bullshit if it's still going to be less correct than Docker anyways? Most people agree (c.f. Docker as opposed to Nix winning too hard in the market).
My approach is different: unfuck Nix.
The whole point is that it allows introducing controlled side effects as long as the output is reproducible.
Bur you're extremely annoying to talk to so I'm not gonna continue engaging. Probably an LLM
This stuff doesn't work, and mixing in ambient environment state is the cross product of the current amount of broken with now it's not even the same on my laptop and desktop.
If you know of an LLM that understands this stuff in this kind of detail, I would be in your debt for a referral, because I sure as hell wish I didn't have to know all this stuff.
And if it's annoying to make vague claims without supporting evidence and have them refuted by concrete arguments with specific details cited than HN may not be the place for you. Being right matters here. I haven't been rude, or made it personal (vis-a-vis "you're extremely annoying" which I don't appreciate).
I don't get the personal attack on this. I'm talking facts about technology.
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.
Meow?
The chezmoi integration with 1Password is excellent; for those who prefer Bitwarden, it supports both the default CLI (which has some inexcusable behaviours for a security product, IMO) and `rbw` (which is infinitely better than the default CLI). It supports `pass`, `gopass`, `passage`, AWS Secrets Manager, KeePass, and several other approaches.
It was the work of a couple of minutes to enable a secret for a Claude Code API token to be mounted in a VM where I'm running Claude for a project where the value is pulled from 1Password and I can regenerate it and reapply without fear.
If one doesn't have to worry about secrets in one's dotfiles, I'm sure that other dotfile managers including Nix with Home Manager will suffice. I do, so they won't.
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.
That's the kicker though. Nix's benefits come from the guarantees it can make based on its integration with the rest of the Nix-controlled ecosystem. Without the control, you don't get the guarantees, and you lose the raison d'être. You need to actively avoid the "value-added" parts (e.g. package options) because latest Homebrew upstream may give you a version that exposes an option that is not yet exposed by the package options, and you can't patch the package with Nix because you're not using a Nix-based package.
Chezmoi is declarative. The templates give me generated configuration. I can rollback anytime I want by reverting Git commits and calling chezmoi apply. It works well within its less-ambitious goals (compared to Nix).
But you also don’t get them at all with Chezmoi, right?
Surely having these guarantees for some packages beats having it for none? In practice _most_ packages you’ll want to use are already in Nixpkgs, and kept up to date.
> You need to actively avoid the "value-added" parts (e.g. package options) because latest Homebrew upstream may give you a version that exposes an option that is not yet exposed by the package options, and you can't patch the package with Nix because you're not using a Nix-based package.
You mean build-time options?
You can usually override the version number/URL in your own configuration to get the new version earlier. But new versions land in nixpkgs-unstable with about the same cadence as Homebrew anyway.
Same thing with runtime options. Want `programs.foo.enableNewThing` but it’s not in HM yet? You can just define that option in your own configuration, no need to stop using the value-added module nor wait for HM.
Eventually, I wrote my own bidirectional sync tool that synchronizes a git checkout (for example, ~/.dotfiles) with the actual home directory. I run it as a systemd service, so I can simply edit or delete files in ~/.dotfiles, and everything else happens automatically.
I can add or remove files in the repository, and they will automatically be created or removed in their synchronized locations. At the same time, the target directories can contain other unrelated files, including an entire $HOME, and this does not interfere with synchronization in any way.
The bidirectional sync is particularly useful when a program, such as vs code, decides to modify its own configuration files, or when I'm feeling lazy and just want to edit ~/.bashrc directly and commit the changes later.
Achieving this requires some careful logic that, hopefully, I've managed to get right. At least at the time I wrote it, I hadn't seen these implemented in other systems.
Oh, and I use the same sync for some files I need to /etc, only for that I run sudo scripts and dont' have a always-on service for obvious reasons.
I'd be happy if someone else found it useful too: https://github.com/senotrusov/etcdotica
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.
Vs. the chezmoi way of keeping everything common except using templates for diverging files.
Pretty snazzy, watching YouTube in Firefox on a 13 year old laptop with hardware h264 decode and everything tuned exactly to my liking.
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.
There's roughly two main ways to manage dotfiles:
- symlink
- copy & sync
The 2nd (what chez moi does) is pretty hard to get right from a UX perspective.
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 have stow too in my micro DE, use it across a few machines and it's holding up really well. I designed my dotfiles so that changes would happens exclusively to files not tracked by stow. I have .zshrc tracked, but environment goes to .zshenv and general local customisation goes to .local/lib/zsh/overrides.zsh (https://gitlab.com/gabriel.chamon/archie/-/blob/main/deploym...). Hyprland config is tracked but device specific configs live in .config/hype/config/device.conf (https://gitlab.com/gabriel.chamon/archie/-/blob/main/deploym...). Deployment instructions/automation is to just copy dist folders in place, which aren't tracked by stow.
It depends on everyone's style. For me personally changes I don't remember having made to files I track in the repo are symptoms that I might need to review how I organize my files. Maybe those changes were something that broke and I forgot to commit after fixing. In any case for me this bidirectional nature of symlinks are a feature, not a bug in this management system.
I don't really recommend it to others, since there's all these great tools that have the features you need (per-machine config, secrets, templating), but I get a deep satisfaction from the fact that I understand every part of this setup from top to bottom. It only has the functionality I need, and I know it doesn't depend on anything that might become unmaintained since it's just POSIX shell scripts.
Even still, I might eventually make the jump to something like chezmoi or nix if I'm not able to implement something I need easily, but that hasn't happened yet.
I thought about using any one of those tools but happily chose shell scripts and symlinks instead. It hasn't let me down in almost a decade with https://github.com/nickjj/dotfriedrice and would highly recommend this approach.
It's basically a 2,500 line shell script to fully automate setting up a system from scratch in a general purpose / opinionated but customizable way that works on Arch Linux, Debian, Ubuntu, macOS and supports WSL 2 in Windows. I have it running on multiple systems, no need to even fork it since it uses patterns suitable for making changes in git ignored files and also has a config file for certain things.
When it comes to setting up a complete desktop environment or even just terminal based tools, dotfiles IMO are more than config files. There's install scripts, packages, system level configs, running commands, OS specific differences and more. It's really nice to be able to run 1 command and have a fresh system ready to go in about 10 minutes.
Shell script is probably my favorite language at this point.
The last few years I've rarely had to switch machines, so maybe chezmoi is overkill now, but it works well, so I'm in no rush to simplify again just for the sake of it (and who knows if I'll need chezmoi's features for real again in the future).
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.
Now I want to use Nix* to manage my multi-machine MacOS and Linux setup (with lots of dotfile config overlap, of course).
That’s the HN experience for you.
Kind souls: what is currently the blessed way to manage MacOS dots with Nix? I recall there is more than one paradigm - what’s the approach that simplest, most robust and can be adopted incrementally?
Edit: Just to say that I think Atuin now also plays in this space. Haven’t checked it out, though.
Now it should be "every app adds features until it manages dotfiles" :D
Dunno why I'd use atuin for dotfile management, but some people seem to like it. It's very good at syncing and managing shell history though.
This one is good, though, and very thorough—even though it's Mac-centric.
You can make forks or branches. Perfect for separating your work specific or private configs
You can use a filter like https://github.com/darkfeline/qualia-go
You can use a shell script (stored in the same git repo). You need you run an external tool with dotfile managers anyway, a shell script gives you more flexibility and doesn't need an extra dependency which might break at an inopportune time. The last thing you need is your dotfile manager breaking when you're setting up a new machine (ask me how I know)
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 run[1]: https://modules.readthedocs.io/en/latest/ [2]: https://lmod.readthedocs.io/en/latest/
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.
https://github.com/logannc/janus
Does Chezmoi have a better solution for that? Or is there a better way using Stow?
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
;)