# Making Nixpkgs less dependent on Bash

**URL:** https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443
**Category:** Nixpkgs Architecture
**Created:** [March 20, 2026, 10:46pm UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443 "2026-03-20T22:46:59Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![anon32574585](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/a/ecccb3/32.png) [@anon32574585](https://discourse.nixos.org/u/anon32574585)
#### Post date: [March 20, 2026, 10:46pm UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/1 "2026-03-20T22:46:59Z")

</div>

> **Fair warning**
>
> _I am not super familiar with the architecture of Nixpkgs, and am mostly basing the following statements on what information I was able to gather from similar threads, as well as on my own assumptions. Feel free to point out any potential nonsense._

I was looking through many different shells recently, and have come to realize that NixOS (or more specifically Nixpkgs) seems to be very reliant on Bash via “bashisms”.

Now personally, I don’t have an agenda against Bash, but making the build systems portable to other POSIX-compatible shells could bring a meaningful benefit to evaluation times when running them against faster shells such as Dash, as well as possibly allowing for toying with the system’s forbidden fruit, better known as `environment.binsh`.

Ridding the build phases of Nix packages of bashisms would likely prove to be a tall order, so I’ve been thinking whether it would be worthwhile to instead try and automate the process with a dedicated tool, through the means of analysis, change suggestions, and maybe even autofixing. Worst case scenario, an actual LSP/formatter would have to give the altered snippets a second opinion, post mortem (and hey, that could also help make the styling more consistent).

And who knows, we may even see the day when someone writes a speed-optimised shell-like evaluator, designed specifically for speeding up preexisting build pipelines, potentially shaving _even more_ miliseconds off build times. Having a POSIX-compliant build stack could certainly come in handy then.

So my questions towards the well-versed are:

- do you know of any packages with particularly convoluted build phases?
- what approach do you think would be best when designing such a tool?
- are there things other than Nix packages that would require “unbashifying”?
- what would be the best way of testing how preexisting packages would fare  
against being built with their phases being evaluated in alternate shells?

---

<div class="post-metadata">

### Author: ![rhendric](https://discourse.nixos.org/user_avatar/discourse.nixos.org/rhendric/32/5699_2.png) [@rhendric](https://discourse.nixos.org/u/rhendric)
#### Post date: [March 20, 2026, 10:57pm UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/2 "2026-03-20T22:57:13Z")

</div>

> [@anon32574585](#):
>
> making the build systems portable to other POSIX-compatible shells could bring a meaningful benefit to evaluation times

I don’t think that could possibly be true. When IFD isn’t in play (as it isn’t in Nixpkgs), evaluation happens entirely prior to anything being executed in a shell. (Unless you meant the evaluation that the shell does and not Nix evaluation, which is what folks around here usually mean when they use the word unqualified.)

This could, as you say, shave some milliseconds off of build times. It’s a rare package whose build time is remotely close to being dominated by what we do in shell.

> [@anon32574585](#):
>
> are there things other than Nix packages that would require “unbashifying”?

Rewriting _activation-time_ components to use faster or non-shell languages is likely to be a far better use of one’s time. (Example: [NixOS: Systemd unit-linking script rewrite for 60x speedups by Profpatsch · Pull Request #479442 · NixOS/nixpkgs · GitHub](https://github.com/NixOS/nixpkgs/pull/479442), though that seems to be foundering on a non-technical conflict.)

---

<div class="post-metadata">

### Author: ![anon32574585](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/a/ecccb3/32.png) [@anon32574585](https://discourse.nixos.org/u/anon32574585)
#### Post date: [March 20, 2026, 11:13pm UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/3 "2026-03-20T23:13:49Z")

</div>

> [@rhendric](#):
>
> Unless you meant the evaluation that the shell does and not Nix evaluation, which is what folks around here usually mean when they use the word unqualified.

Yes, I meant shell evaluation.

---

<div class="post-metadata">

### Author: ![anon32574585](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/a/ecccb3/32.png) [@anon32574585](https://discourse.nixos.org/u/anon32574585)
#### Post date: [March 21, 2026, 9:10am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/4 "2026-03-21T09:10:27Z")

</div>

Maybe I have overemphasized the wrong thing. So to be clear, to me, the actual biggest potential benefit of doing something alike what I have proposed would be making the `environment.binsh` option user-configurable.

And sure, the upsides of switching out the system shell would likely still be negligible, but some other distros are doing it, and I just find it to be a reasonable thing one might want to customize (albeit some sanity checks would be in order, such as checking whether the selected package is a POSIX-compatible shell).

I’m fine with trying to help out with such a refactor, and am just looking for directions and/or interest.

---

<div class="post-metadata">

### Author: ![mightyiam](https://discourse.nixos.org/user_avatar/discourse.nixos.org/mightyiam/32/33998_2.png) [@mightyiam](https://discourse.nixos.org/u/mightyiam)
#### Post date: [March 21, 2026, 10:03am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/5 "2026-03-21T10:03:44Z")

</div>

Hrm… it seems that the title of this post should be more like “Making NixOS less dependant on bash”, would you agree?

If that’s the case, then I think most would agree, as there has been an effort towards that end, such as the one you’ve been (by chance) referred to.

Personally, I would like to see bash scripts generally everywhere replaced with nushell scripts. They’re safer, have incomparably better errors and the developer experience is oil tankers ahead. But nushell itself is compiled by rust, which we currently bootstrap from upstream binaries, which is less desirable than the nice bootstrap from source I guess we have leading to bash.

If you’re interested in pursuing something, consider finding or asking for a concrete task.

---

<div class="post-metadata">

### Author: ![anon32574585](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/a/ecccb3/32.png) [@anon32574585](https://discourse.nixos.org/u/anon32574585)
#### Post date: [March 21, 2026, 11:50am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/6 "2026-03-21T11:50:41Z")

</div>

> [@mightyiam](#):
>
> Hrm… it seems that the title of this post should be more like “Making NixOS less dependant on bash”, would you agree?

I have assumed most of NixOS’ current Bash dependency stems from Nixpkgs, hence the title and category. But yes, that’s entirely fair.

> [@mightyiam](#):
>
> Personally, I would like to see bash scripts generally everywhere replaced with nushell scripts.

Without a doubt, but my proposed approach could serve as an _intermediary_ solution - one that would likely not spark too much opposition, since at the end of it, the build phases would still work with the current tooling (Bash).

Even in the aforementioned Github issue, there was some discussion regarding which language should be used for the specific reimplementation, which is a topic I’m not qualified enough to give opinions on, but am still able to realize it could be particularly controversial when considering a repository-wide change.

The amount of labor is also a concern. Nixpkgs is large, and there is a reason why I have proposed the creation of some sort of automated tool to help with the process of merely _refactoring_ some of its syntax (a tool that could also be used with scripts completely unrelated to Nix or NixOS). Switching to a different scripting language would require much more upfront labor.

Also, since I imagine this process could require reimplementing a handful of Bash-specific features, I’m curious whether it would be viable/reasonable to reduce code duplication via the creation of some sort of Nix library whose functions could be concatenated within the build phases.

---

<div class="post-metadata">

### Author: ![toastal](https://discourse.nixos.org/user_avatar/discourse.nixos.org/toastal/32/3454_2.png) [@toastal](https://discourse.nixos.org/u/toastal)
#### Post date: [March 21, 2026, 7:54pm UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/7 "2026-03-21T19:54:01Z")

</div>

I had [played around](https://smeder.ee/~toastal/dash-nix) with some basic Dash stuff (which I think Debian/Ubuntu still use as the default shell, no? It is smaller & faster) as `builtins.derivation`. It works, but what I miss is the ability to prefer local building like `pkgs.runCommandLocal` as it’s tied to `stdenv` which is tied to Bash.

Pointing out Bashism in reviews seemed to annoy folks as “the whole system relies on Bash anyways”. Which is true, but the bandwagon isn’t always the best approach; perhaps it could be worthwhile to push back on Bashisms before they would creep further in. `checkbashism` could theoretically be ran say on new commits assert no new ones are being added.

---

<div class="post-metadata">

### Author: ![rnhmjoj](https://discourse.nixos.org/user_avatar/discourse.nixos.org/rnhmjoj/32/1792_2.png) [@rnhmjoj](https://discourse.nixos.org/u/rnhmjoj)
#### Post date: [March 21, 2026, 8:02pm UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/8 "2026-03-21T20:02:12Z")

</div>

> [@anon32574585](#):
>
> Maybe I have overemphasized the wrong thing. So to be clear, to me, the actual biggest potential benefit of doing something alike what I have proposed would be making the `environment.binsh` option user-configurable.

That option is already “user-configurable”, it’s just hidden, for some reason. The description

> Please note that NixOS assumes all over the place that shell to be Bash, so override the default setting only if you know exactly what you’re doing.

is hyperbolic. I have been using `environment.binsh = lib.getExe pkgs.dash` for years with no issue at all. All scripts generated by NixOS have a shebang with an appropriate shell and never use /bin/sh for purity reasons. The only thing you could reasonably worry about is the libc `system()` function using /bin/sh, but since many distros (rightly) don’t set it to bash, most software generally assumes it’s a generic POSIX shell.

---

<div class="post-metadata">

### Author: ![anon32574585](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/a/ecccb3/32.png) [@anon32574585](https://discourse.nixos.org/u/anon32574585)
#### Post date: [March 21, 2026, 8:22pm UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/9 "2026-03-21T20:22:54Z")

</div>

> [@rnhmjoj](#):
>
> That option is already “user-configurable”, it’s just hidden, for some reason. The description

I have come across [an opposite statement](https://github.com/NixOS/nixpkgs/issues/270978#issuecomment-1834131631) from a Nixpkgs contributor.

It’s great to hear you’re not having issues with the option yourself, though.

---

<div class="post-metadata">

### Author: ![waffle8946](https://discourse.nixos.org/user_avatar/discourse.nixos.org/waffle8946/32/27221_2.png) [@waffle8946](https://discourse.nixos.org/u/waffle8946)
#### Post date: [March 21, 2026, 8:36pm UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/10 "2026-03-21T20:36:19Z")

</div>

Many nixpkgs packages do unfortunately call `/bin/sh` directly. I use a script that logs such actions to the journal, haven’t gotten around to fixing many of them though.

My goal is to eventually just null out `binsh` and `usrbinenv`.

---

<div class="post-metadata">

### Author: ![anon32574585](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/a/ecccb3/32.png) [@anon32574585](https://discourse.nixos.org/u/anon32574585)
#### Post date: [March 21, 2026, 8:59pm UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/11 "2026-03-21T20:59:42Z")

</div>

> [@toastal](#):
>
> It works, but what I miss is the ability to prefer local building

I’m not sure whether it’s what you mean, but passing `--option substituters ""` to `nixos-rebuild` seems to disable the use of non-local caches for the rebuild (aka [cache.nixos.org](https://cache.nixos.org), by default), but I can’t really be sure, as my rebuilds currently fail due to downtime of [busybox.net](https://busybox).

Come to think of it, the cache may also be the reason behind @rnhmjoj’s success with the `environment.binsh` option.

I still don’t know how to attempt building all of Nixpkgs for testing, say 100 packages at a time (because SSD storage is really expensive right now), and I don’t think I’ll be resorting to adding them to my system config manually.

---

<div class="post-metadata">

### Author: ![tejing](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tejing/32/4566_2.png) [@tejing](https://discourse.nixos.org/u/tejing)
#### Post date: [March 22, 2026, 12:25am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/13 "2026-03-22T00:25:39Z")

</div>

Writing _robust_ shell code without relying in bash-isms is _hard_. Particularly the lack of array variables is painful. You have to code in circles to get around the limitations. I wouldn’t support removing them from nixpkgs build code if it costs in readability and maintainability of stdenv and nixpkgs in general, which I am convinced it would.

As for `/bin/sh`, it’s a dependency of a _lot_ of things. I do think we should avoid nix-packaged things depending on it as much as we can, but I believe even statically-compiled binaries for general linux often rely on it to interpret calls to external commands. If you remove this, then many statically-compiled binaries would no longer work on nixos, which was apparently a bridge too far when originally designing the os. There’s an argument to be made for removing it, but it’s really hard to argue it’s worth it.

Also, we need `/usr/bin/env`. For hashbangs. Not really necessary for anything else, but having hashbangs do `PATH`-lookups is kind of important.

---

<div class="post-metadata">

### Author: ![rnhmjoj](https://discourse.nixos.org/user_avatar/discourse.nixos.org/rnhmjoj/32/1792_2.png) [@rnhmjoj](https://discourse.nixos.org/u/rnhmjoj)
#### Post date: [March 22, 2026, 8:11am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/14 "2026-03-22T08:11:16Z")

</div>

> [@anon32574585](#):
>
> Come to think of it, the cache may also be the reason behind @rnhmjoj’s success with the `environment.binsh` option.

If you’re implying /bin/sh is used during a build, that’s not true. In the Nix build sandbox /bin/sh is symlinked to ash, regardless of what the builder actual /bin/sh is.

/bin/sh and /usr/bin/env only really matters for software you’re running on your machine, they’re almost immaterial in relation to Nixpkgs infrastructure

> [@waffle8946](#):
>
> My goal is to eventually just null out `binsh` and `usrbinenv`.

I think that /bin/sh could be easily dealt with by patching glibc. See [#1424](https://github.com/NixOS/nixpkgs/issues/1424). I bet that most uses are just calling `system()`.

/usr/bin/env can already be removed without much consequences, because there aren’t really scripts built by Nixpkgs that uses it as a shebang.

If you need it for covenience in your own scripts, you can reimplement it with a binfmt interpreter:

```auto
environment.usrbinenv = null;
boot.binfmt.registrations.env =
  { interpreter = pkgs.writers.writeDash "env"
      ''
        args=$(head -n1 "$1" | cut -d' ' -f2-)
        env $args $@
      '';
    magicOrExtension = "#!/usr/bin/env";
  };

```

The real problem with `usrbinenv = null` is that without `/usr` a bunch of software, most notably systemd, craps out. For example, services that use sandboxing options like `ProtectSystem=true` will try to bind-mount /usr and fail, because systemd insists that these paths must exist (see [systemd#18867](https://github.com/systemd/systemd/issues/18867)).

---

<div class="post-metadata">

### Author: ![anon32574585](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/a/ecccb3/32.png) [@anon32574585](https://discourse.nixos.org/u/anon32574585)
#### Post date: [March 22, 2026, 9:08am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/15 "2026-03-22T09:08:46Z")

</div>

> [@tejing](#):
>
> Particularly the lack of array variables is painful.

It seems somebody has already written a [POSIX reimplementation of some Bash array operations](https://github.com/friendly-bits/POSIX-arrays).

Depending on the particular variant of the script, the addition could end up being pretty lengthy, so my earlier suggestion of creating a POSIX shorthand library could be necessary.

It is GPL-licensed (unlike Nixpkgs), so I’m guessing I would have to write my own version anyways (for the sake of not cluttering the repository with extra license files, and taking advantage of implementing it as a Nix library).

---

<div class="post-metadata">

### Author: ![toastal](https://discourse.nixos.org/user_avatar/discourse.nixos.org/toastal/32/3454_2.png) [@toastal](https://discourse.nixos.org/u/toastal)
#### Post date: [March 22, 2026, 10:17am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/16 "2026-03-22T10:17:25Z")

</div>

> [@tejing](#):
>
> Writing _robust_ shell code without relying in bash-isms is _hard_. Particularly the lack of array variables is painful.

I wouldn’t disagree, but should the shell be something you opt into as most derivations aren’t using arrays? I think I had a look & stdenv, _could_ be Bash-less.

---

<div class="post-metadata">

### Author: ![tejing](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tejing/32/4566_2.png) [@tejing](https://discourse.nixos.org/u/tejing)
#### Post date: [March 22, 2026, 10:25am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/17 "2026-03-22T10:25:55Z")

</div>

I also have to question what exactly the goal really is here.

> [@anon32574585](#):
>
> making the build systems portable to other POSIX-compatible shells could bring a meaningful benefit to evaluation times when running them against faster shells such as Dash

Highly questionable. Firstly, using a different shell would affect _build_ times, not evaluation times. For most users this would be very little effect since almost everything they do is cached. For actual compiles that aren’t cached, the shell used is far from a relevant performance impact.

This could have a slight effect on the “glue” derivations that put things together locally, like the derivation that builds the symlink environment from the set of installed packages, but those derivations (aside from the man cache, which is not a shell issue) are already fast enough I doubt I would ever care about the difference.

> [@anon32574585](#):
>
> as well as possibly allowing for toying with the system’s forbidden fruit, better known as `environment.binsh`.

Should be unrelated. The shell used in the build environment has nothing to do with the setting of `environment.binsh`.

---

<div class="post-metadata">

### Author: ![tejing](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tejing/32/4566_2.png) [@tejing](https://discourse.nixos.org/u/tejing)
#### Post date: [March 22, 2026, 10:32am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/18 "2026-03-22T10:32:10Z")

</div>

> [@toastal](#):
>
> I wouldn’t disagree, but should the shell be something you opt into as most derivations aren’t using arrays? I think I had a look & stdenv, _could_ be Bash-less.

Why would this ever be configurable? What could possibly be beneficial enough about using a different shell to get the exact same work done that it would be worth losing the entire binary cache? Seriously, what’s the goal that justifies the amount of work and continuing maintenance burden involved in supporting more shells than bash?

This doesn’t affect what shell a user actually uses, what the `/bin/sh` symlink points to, or even whether bash is _installed_ on a (non-build) machine.

---

<div class="post-metadata">

### Author: ![TLATER](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tlater/32/4257_2.png) [@TLATER](https://discourse.nixos.org/u/TLATER)
#### Post date: [March 22, 2026, 10:45am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/19 "2026-03-22T10:45:43Z")

</div>

I think a far more interesting discussion would be “making nixpkgs less dependant on POSIX-ish shells”, because seriously `stdenv` is really hard and counterintuitive to use and also writing \*sh code sucks; POSIX simply wasn’t designed for writing maintainable code.

Existing hooks and various subcomponents of the conglomerate, especially if you include the various things that derive from `stdenv`, also have almost zero indexable documentation, IMO caused by it being a messy pile of shell code; this is worse yet than the general doc situation in nixpkgs, where at least most of it has _something_ resembling an API, even if it’s hard to find. For hooks and build systems you’re mostly in the wild west and just have to read the code, assuming you can even find it.

It’d be cool to completely overhaul this in some language that is better suited for all of this. But of course, that’s also a significantly more involved piece of work.

And yeah, completely separate from the topic here, there isn’t much of a benefit to changing `stdenv` to a non-bash POSIX-ish shell; the code would barely change (likely to be even less maintainable, not more), and it has next to no impact on users.

The only minor benefit I can imagine is a small performance improvement for builds, but it’d probably be vanishingly small. If you can benchmark this somehow (probably not _too_ difficult to comment out all the actual work-doing parts of nixpkgs builds) and show a meaningful difference @anon32574585, maybe people would be more keen on this suggestion.

---

<div class="post-metadata">

### Author: ![7c6f434c](https://discourse.nixos.org/letter_avatar_proxy/v4/letter/7/8e7dd6/32.png) [@7c6f434c](https://discourse.nixos.org/u/7c6f434c)
#### Post date: [March 22, 2026, 10:50am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/20 "2026-03-22T10:50:00Z")

</div>

> [@tejing](#):
>
> For actual compiles that aren’t cached, the shell used is far from a relevant performance impact.

There are some builds where sequential `configure` is a large part of the build time on multi-core machines… but what shell `configure` uses is of course independent from what shell `stdenv` code uses.

---

<div class="post-metadata">

### Author: ![tejing](https://discourse.nixos.org/user_avatar/discourse.nixos.org/tejing/32/4566_2.png) [@tejing](https://discourse.nixos.org/u/tejing)
#### Post date: [March 22, 2026, 10:59am UTC](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443/21 "2026-03-22T10:59:27Z")

</div>

@TLATER Yeah, shell is an ugly language littered with footguns that lacks a bunch of nice abstractions. But honestly, what you would replace it with? There aren’t a lot of languages that wouldn’t make the main kind of work we’re currently doing with bash unbearably verbose and hard to understand. I’ve never really found a “better shell language”. For the things it’s best at, it really is best at them. The one thing I can think of that might do the job alright would be nushell, but its build closure is unacceptably large for stdenv, and I don’t think I’d be comfortable making a relatively new project completely vital to nixpkgs architecture.

@7c6f434c Yeah, I could see running `configure` with a faster shell by default if that could get meaningful improvements. That would be a comparatively compartmentalized change with some meaningful chance of clear benefits.

[Next page](https://discourse.nixos.org/t/making-nixpkgs-less-dependent-on-bash/76443.md?page=2)
