- As mentioned by another commenter you will not be able to run random binaries by default. You can use nix-alien[2] which will automatically fetch the required libraries and build an FHS environment for the binary.
- It is significantly more bandwidth- / rebuild-heavy. If an input for a derivation changes it will trigger a rebuild, which means either a redownload from the binary cache or a recompilation.
[0] https://github.com/tazjin/nix-1p
That seems weird to me. I don't have to learn package configuration language in other distributions. I thought that one could just install packages with a package manager.
> You can use nix-alien[2] which will automatically fetch the required libraries and build an FHS shell for the binary.
That's actually fine. I want to put closed source software into a chroot anyway.
NixOS is more like a distro bundled with Ansible, so you can describe your entire system as code.
If you just want to use nix for packages, you can run any distro and install nix the package manager into it. This is a good way to dip your toes in the water. And in that case you can just use the cli commands for installing packages.
I still encourage you to give it a try. You can build different versions of same package and not "install" them. Instead just execute the binary from the built version (I do this where I have a built-but-not-installed version of openssh-8.6 laying around because I have an old service that modern SSH no longer supports).
You can also run `nix-shell -p <custom-package-version>` to get a shell with a specific package available in the path, overtop of whatever might be globally installed.
Who knows, you might even be tempted to dip your toes into the Nix language by writing a custom `shell.nix` to build a shell with some more complex development environment, or to simply automate a complex `nix-shell -p` command.
You can browse some here: https://search.nixos.org/options
For example, to install an OpenSSH server and run it, you'd write:
services.openssh.enable = true;
and to run it on an additional port, 2222, instead of just the default of 22, you'd write: services.openssh.ports = [
22
2222
];
For programs you don't need to configure but just want to put on your PATH, you just add them to a list like environment.systemPackages = [
pkgs.firefox
pkgs.jq
];
If configuration management isn't for you, go ahead and mess around with Nix as a standalone package manager. But NixOS really doesn't require much effort or prior knowledge to get up and running and start playing with it!(For NixOS, the Nix you write only starts looking like real code when you want to add new features or some packages to NixOS.)
The above is sometimes true and sometimes not. For the most part, Nix can install multiple versions of a program but only one can be in use at any given time.
Nix is for the most part shell based workflow (as in bash, zsh, etc.). The `nix-shell` command lets you switch out the packages (and versions of packages) that are used in any given shell, but it works off of a configuration file written in the Nix language that you write. The programs that are available are controlled by environment variables such as PATH and MANPATH.
Nix is a big shift from the usual way of dealing with packages, programs, etc. It isn't really useful until you really make the effort to understand what is going on, learn the Nix language, etc. If you are not interested in "programming" your system, then it probably isn't for you.
That’s not really true and is only a limitation of how PATH works on UNIXes (the first match is used). But you can for example add an aliased name for multiple versions of the same package, or for another meaning of use you can have different executables in the same environment different versions of the same lib (e.g. one bash script references python3, the other python3-at-specific-patch/minor-version/whatever)
That's a bit hand-wavey. More precisely: when you run a command, like `python3`, you can only associate that with one file. If you want multiple Python 3 interpreters, you'll have to use different names (e.g. making symlinks).
Alternatively, you don't need to bother "installing" anything; e.g. I use Nix for projects which use Scala, Maven, Python, NodeJS, etc. yet I don't have any of those installed. Instead, each project includes a `shell.nix` file which specifies the tools it wants. Running `nix-shell` in different folders gives me access to different tools.
Also, with Nix we only need to care about the end result: we can "install" a bunch of different programs, even if they have incompatible dependencies, since we're not "installing" those dependencies. ("Install" just means putting a symlink in some bin/ folder, like /run/current-system/sw/bin on NixOS or $HOME/.nix-profile/bin on non-NixOS)
You could use the command
nix-env -iA mypackage
To install packages, which is like pacman -S mypackage or apt install mypackage.But... the interesting part of Nix is that it lets you install packages declaratively, by editing a config (like vim and emacs packages). Besides installing packages, all configuration is done through this config file (or bunch of config files): nix generates all files in /etc for you, again, like vim or emacs, but for the whole OS
That way, you easily transfer your setup to another computer or even keep two machines in sync. And you can add it to version control. And you get a grub menu with all your previous setups (until you uninstall them)
If this doesn't appeal you, you probably won't like to use NixOS
For general usage I didn’t notice it much, like, as an alternative to apt/pacman/etc. Ok, maybe don’t use it from a limited data plan (but isn’t true of every desktop OS?).
But sure, if you patch some lib n layers deep you will have to recompile many things, which is a godsend (in that you can actually do that), but will take a bit of time. But you can usually decrement its impact by really changing what has to be changed and using a “standard” channel for all the rest. With flakes it is especially easy to mix and match multiple nixpkgs repos at different versions.
Documentation and naming conventions for Nix are absolute shit across the board. This will get downvotes, and people will say I'm wrong, but I'm 100% right. Go see yourself, it's bad. Language is called Nix, OS is actually called Nix, package manager is called Nix, just the whole thing seems like it was written in 1 week by a squirrel with 12 hands and a sack of ritalin.
That being said a lot of smart people here and in my peer group swear it's the truth, despite none being able to elevator pitch it.
Like Docker, but works.
The notion of portability is Docker's bread and butter. With proper version pinning you _might_ get lucky with repeatability too. Most people anticipate repeatability to be part of portability, but it really is a distinct notion.
> it wouldn't be surprising if it does not build at all.
This part is a stronger point, and it's true. When you repeat something and what you get is not just a different version or variation but something with totally different or broken behavior, that seems bigger than an ordinary failure of reproducibility.
Like Ansible but more bdsm.
Linux not making you feel superior anymore? Try Nix!
- NixOS: Full OS that says "what if we did the same for the whole OS"
Nix solves what Docker merely works around.
The secret of Nix is the application of the common wisdom of memory management discipline in modern programming language design to the process of building and distributing software.
The payoff is, as with garbage collection in the original case, and immense leap in safety, productivity, and maintainability for software build and deployment systems.
Concretely, Nix and the ecosystem of tools built upon it and each other mean:
- configuration management that never drifts
- upgrades that can always be rolled back in seconds
- servers that don't accrue cruft
- software whose bill of materials comes for free
- an end to version conflicts
- packages which can always be bundled into a minimal container image in seconds
- build artifacts which turn out the same no matter where or when you build them
- software running as-needed, even locally, without having to be installed or manually cleaned up
- a single, simple language capable of defining your entire stack, from building individual assets to managing cloud infrastructure to deploying service-oriented systems
- an end to 'works on my machine' bullshit in their development environments *without* the inefficiencies of virtualization— even on macOS
- user-mode package management for supercomputers and mainframes
- the ability to boot into yesterday's workstation with two keystrokes at boot time
- a time machine for running obsolete software which can't build on modern systems
- a time capsule for software research being conducted today
- the largest, most up-to-date package collection in the world
and much more. The benefits and applications and extensions of Nix are so startlingly vast and diverse because ultimately, the Nix ecosystem is not an iteration on a tool— it's a renaissance. You should join it and start shedding obsolete problems.Not true. The distro is called `NixOS`. The package manager and it's language is called `Nix`.
I do agree that the learning curve is extremely steep.
Maybe call the package manager something catchy like "pacman" or "update_software_from_repos" :)
Yep; that's a bummer. The manual calls it the "Nix expression language", and some people refer to it as "nixlang" (similar to Gophers saying "golang")
> OS is actually called Nix
Nope, it's always NixOS; 100% of the time. In fact, the naming confusion goes the other way in this case, since the whole project (Nix, NixOS, etc.) lives on the domain nixos.org, and the GitHub account NixOS!
> package manager is called Nix
The commands are called Nix; but I personally find the idea of "package manager" just complicates things. Nix is more of a build tool, like Make; internally, it uses "derivation" to refer to anything from a text file to an entire OS. An application, like a music player, may involve many derivations (e.g. a derivation for its source code, a couple of derivations containing patches, a derivation for an interpreter with the required libraries, etc.); indeed the "actual program" in our $PATH is often just a script which invokes some other binary defined via a different derivation ;)
more commonly just nix language or you know it out of context
No, not really. They are not consistent for every part and not every package is up to date with everything but if you get the gist you can easily guess things. If things are really weird we can always rename them.
OK, I’ll bite.
Nix is a build system. NixOS is a Linux source distro built on top of it (cf Gentoo, gittup, BSDs). Except you won’t need to build anything.
Nix builds (should) execute in an isolated environment, thus the build artifacts are (ideally) bit-for-bit identical no matter where they were built. This means you can have a shared artifact cache (cf Bazel). Now for the clever part: in a distro, such an artifact cache is the same thing as a binary repo. Thus you are in fact using a (somewhat disk-space-hungry) binary distro until you want to patch something, at which point it transparently reverts to a source one (up to and including rebootstrapping the system compiler if you wish).
That’s the gist, but there are some more goodies on top of that.
First, none of this really requires a NixOS-only world. Thus, as an intermediate step, there’s Nixpkgs: a ports-like collection of packages that runs on conventional Linux and macOS systems (*BSD support is possible but has bitrotted). To maintain isolation in such an environment, all binaries it builds refer to dynamic libraries by build hash rather than load whatever’s present, and are usually wrapped to ensure other parts of the ambient environment don’t leak through. But once you’ve done that, more or less the only thing remaining to have a “gimme a shell with P, Q, and R in it” command is to point PATH to the right build directories. Hermetic build environments (cf virtualenv) for any supported language, user-scoped rootless package installs, good stuff.
Second, what NixOS adds on top of that (apart from a kernel) is a system for building system configurations out of Nix-language descriptions. It’s a bit clunky, like all config generators, but once you commit to maintaining all of your /etc that way a full rollback of (the NixOS-managed part of) the system is a single GRUB selection away. There are also things like “run a QEMU with this system config inside”, “build a Docker-compatible image with this system config inside”, etc.
Finally, as to how this works, Nix the build language is really simple, it’s JSON + (pure) functions + laziness + a build recipe type. Usually you just generate some shell or Perl or whatever scripts and stuff them into the recipe, so for Nixpkgs it’s honestly a bit overkill, but NixOS uses it to define a rather clever system with options that (if defined) set values of other options that ... all the way to the options that define the raw content of each file in /etc, with rules for merging option values if you wish (cf CUE, Dhall). If your mental model of your system is more abstract than the configuration of each individual service, it’s not hard to write it down as Nix code that defines some new NixOS options, then define your system—or several—in terms of those options.
Bad parts:
Apart from the build system as such, the CLI includes support for a lot of the idioms I mentioned above, so the separation may not look that clean. (This is not helped by the fact that a complete CLI overhaul is in progress, with old commands like nix-build and nix-env being superceded by a single new one, nix. The nixos-* ones are separate for now.)
The language is perhaps a bit too minimal and lacks a standard library, so Nixpkgs ends up containing that as well, without much in the way of documentation. You will have to refer to the source there. The library is mostly simple list and mapping utilities, so it’s not difficult, but figuring out whether the thing you want is in it or not can be frustrating, and the API won’t win any beauty contests.
It can be slow.
Now that I’ve written this, I see I can’t really phrase the benefits such that the result is neither a shallow-sounding platitude nor a laundry list of features, when the reality is a laundry list of features that mostly fall out of a couple of overarching ideas. And it’s not like each of those features haven’t been done before, but this particular implementation comes out remarkably simple and sane given the length of the list.
Perfectly reproducible OS with easy rollbacks. OS never gets crufty, no need to reinstall every release version or two. Single configuration language for all apps and system components. Composable and shareble config modules at any level of abstraction, e.g. you can piece together many git repos to custom roll your OS. Isolated dependencies for every package, meaning no dependency hell (similar to docker). You can have multiple versions of everything running live. Ability to run temporary environments using the same config language.
Current OSes are like VAX or TRS-80 in comparison. Nix-likes are the future.
Nix the set of tools gives you convenient command line tools that can: evaluate Nix language expressions, build recipes, analyze build-time or run-time dependency graphs of a recipe, give you ephemeral shells with the packages you want in scope but not installed "globally", package management tools to install packages globally, and recipe diffing tools so you can see how recipes changed.
Nix the package manager is a convenient, gigantic, community effort to explicitly describe how to (reproducibly) build almost all of the OSS software that users need and it comes with a substitution cache so that most recipe build products are easily substituted when installing, so you don't have to build. Even if you don't use Nix, nixpkgs is still impressive because you have the most explicit documentation for how to build a piece of software from source and all of its dependencies than anywhere else on the internet, it usually rivals project author's in its specificity, explicitness, and clarity.
NixOS the Linux distribution combines all of this together with a convenient configuration module system and generally good defaults to give you an operating system that is declaratively specified from your etc hosts file all the way down to the recipe for building the kernel, a rich and granular dependency graph, reproducible OS configuration builds, and diffs between closures.
My biggest gripe with Nix is the lack of static types. This was the originator's biggest mistake that Nix will be living with for a very long time to come. Static types would have helped bring the learning curve down IMHO and made it easier to document and less frustrating to debug.
That being said, the overall properties of Nix, nixpkgs, and NixOS far outweigh the pain points in my six years of production experience with it and for what we care about: auditability, reproducibility, explicitness, efficiency, and integrity.
so basically, when you install something with nix, it's specified all the way down to the bare metal (except for perhaps the kernel)
Nix and Nixpkgs are messy, evolved things with a lot of history and quirks. They're also very powerful tools that can change the way you even approach computers. If you stick with them long enough, they may inspire you to extend and leverage them in creative ways... continuing the process of messy evolution. :)
If Nix is CVS or even Subversion, I'm hoping for Git.
Everything about Nix can be trivially refactored. Every part is neatly isolated from the rest.
Tweaking a few NixOS modules it replacing a package is easy, but neither the Nix codebase nor Nixpkgs is characterized by perfect modularity or uniform layering.
Don't get me wrong - I love NixOS! I'm gradually switching my infrastructure to NixOS. There are very necessary reasons for Nix's departures. But it is jarring, and if we want converts we have to manage expectations properly!
> Look ma, no /usr/lib
and right after that it's a chat about the Nix store, and then a tour of what all those ugly hashes let you achieve.
I guess when I wrote that comment I was mostly thinking about what it's like to administer NixOS on a personal system over the moderate term, not the initial shock and wonder of hiking through the glorious Nix symlink forest under /nix/var/nix/profiles for the first time. :)
Mutable distros you directly edit stuff in /etc, then build your knowledge on top of that foundation. Whatever better practices you end up adopting, you're still ultimately modifying files in /etc (and probably elsewhere). A NixOS beginner shouldn't be touching config files, and can't even do things like replace a binary with a shell script wrapper to understand when and how a program is run by a different program.
So I see that departure as a pretty huge one, that will affect someone learning Linux on NixOS for many years, as they need to dig through NixOS specific docs to understand how they're supposed to configure something, rather than falling back to the regular packaging docs. Whereas with Debian you only need Debian documentation to know how to install a package, but after that the upstream package documentation tells you everything else.
As an aside, I feel like NixOS asks a fundamentally different question - "how can we mitigate Linux/Unix's complexity" rather than the traditional mutable distro question of "how can we best interact with Linux/Unix's complexity".
(Also, that sounds like a great approach to explaining NixOS!)
That's true. Once you have found your footing with the Nix language and figured out some basics of how to navigate the NixOS modules in Nixpkgs, the latter becomes a rich source of examples on how to configure everything on a modern Unix-like system, from mounting a btrfs subvolume in your initrd via systemd/dracut integrations to setting up PipeWire to emulate PulseAudio. But while NixOS can still teach you a lot about how a working Unix-like system is put together and how its stack is configured, the most useful point of entry for such exploration is very different from what you might be used to on other distros.
You can also learn by exploring the Nix profiles and the Nix store of a working system, much like you would walk through the FHS on a ‘normal’ Linux system— after all, all of your system-wide config files can eventually be hunted down in the Nix store. If you run `ps` on a NixOS system, you'll see explicit references to RC files for lots of programs that are wrapped to point to specific config files, and for running persistent services. But it's probably not as useful as going directly to the Nixpkgs source, once you've learned to read a little Nix.
> A NixOS beginner shouldn't be touching config files, and can't even do things like replace a binary with a shell script wrapper to understand when and how a program is run by a different program.
That's an interesting thought. I didn't come to NixOS as a beginner in the Linux world; NixOS was not my first distro. (I think that's true for most of us in the community.) With NixOS, neither the paradigm nor the community really encourages the kind of monkey patching, that kind of learning by brute intervention on a running system. Even so, I think it would be possible (if perhaps a bit perverse) to write a textbook or a course like ‘Learning Unix with NixOS’. I think using a read-write store as a teaching tool before showing the reader how to use Nix itself to wrap programs that live in the Nix store would be fine.
> [NixOS users] need to dig through NixOS specific docs to understand how they're supposed to configure something, rather than falling back to the regular packaging docs.
Right, NixOS definitely changes the sort of ‘order of recourse’ users will want to make when configuring a piece of software. I'd say it looks something like this:
1. Is there an existing NixOS module for configuring the software I want to use?
2. If so, does the module have any high-level options that look so convenient that I should try them right away?
3. Is there any additional, special configuration that I need to do?
If the answer to (1) is no, or the answer to (3) is yes, then it's definitely necessary to consult the upstream documentation on the software you want to use. In the case that a module exists but you need special config, there will always be a way for you to pass configuration options defined upstream directly to the application through your NixOS configuration.A NixOS fanatic might frame this
> Whereas with Debian you only need Debian documentation to know how to install a package, but after that the upstream package documentation tells you everything else.
in an alternative way:
> Whereas Debian only helps you to install the package, NixOS will also help you perform common configuration tasks. It's only when you need to perform peculiar configuration tasks for your specific needs that you really have to dive into the upstream documentation.
At the same time, knowledge of some upstream component (e.g., Xorg, connman, OpenSSH, etc.) always remains applicable with NixOS, if you want it to be. Everything that's configurable under /etc/something/or/other on Debian remains configurable on NixOS in a straightforward way, either by specifying key-value type config in the Nix language or (in the worst case) by embedding a config file snippet in your NixOS configuration.
> As an aside, I feel like NixOS asks a fundamentally different question - "how can we mitigate Linux/Unix's complexity" rather than the traditional mutable distro question of "how can we best interact with Linux/Unix's complexity".
I think this is well put, and it's what I was getting at above with the idea that thinking about the particular structure of some program's RC file is a last resort in NixOS. But it's not entirely one-sided! The NixOS module system serves not just to shield users from that complexity when they don't need to confront it, but also to teach them about it when they do. For me, that's one of the reasons that learning the Nix language and exploring the Nixpkgs codebase is so worth it.
but it's just a few lines in your config and then it works
hardware.opengl = { extraPackages = with pkgs; [ intel-compute-runtime # OpenCL library intel-media-driver # video encoding/decoding hardware accerlation ]; extraPackages32 = with pkgs.pkgsi686Linux; [ intel-media-driver # video encoding/decoding hardware accerlation ]; };
If you want an FHS, you can get one using a function like buildFHSUserEnv (that's defined in the Nixpkgs project; Nix itself doesn't know or care what FHS is; indeed, Nix will happily run on non-Linux platforms)
The vpn client at work wasn't available for the latest ubuntu and the old version did not work due to changes in some libs. Wrapping it with nix providing the right libs was way easier and much more replicable than manually building the required stuff. Did in on my machine and than 3 mins to do the same for a colleague.
Its the first distro I've used in 20 years that doesn't feel like a stiff wind could cause the whole thing to collapse and catch fire in an unrecoverable way, while still allowing me to run any software I want instead of just what is in some limited curated repo. And unlike Nix, I didn't need to learn a new language to use it.
toolbox create new_dev_env_or_whatever
toolbox enter new_dev_env_or_whatever
dnf install all_the_things
And now you've got a container with whatever installed. To use it you do have to use `toolbox enter` or `toolbox run` though. Distrobox is basically the same thing for people who don't use Fedora.I have my issues with both Flatpak and Toolbox as far as how they're put together and work, but overall I find it to be a vast improvement on the status-quo way of doing things. YMMV, of course.
The limitations are:
1) Each invocation of the package manager (install/upgrade/uninstall, the usual stuff) results in a new OS 'commit' and requires a reboot to switch to it.
This is the entire point of the distro (random .rpm broke your system? just rollback), and is why Silverblue users generally only use DNF packages for low-level tools and run regular applications as flatpaks, appimages, or podmans.
2) Occasionally you'll run into a package that wants to write to a folder that Silverblue made read-only and version-controlled, and breaks. In that case your only options are to run the package inside a toolbox (a special Podman container that comes with Silverblue for these scenarios), or patching the package.
https://gitlab.com/ahayzen/silverblue-nix
NixOS people will prefer NixOS, but Silverblue seems like a nice complement to Nix if you need an FHS base system and want to retain some Nix-ish features like rollbacks and atomic upgrades.
It works very well for me under Ubuntu these days, but if I can get it working equivalently well on NixOS I may legitimately consider switching.
First, this is a whole system specification. This means that executing this on Nix will build you a whole OS image. You can build the image if you have Nix by running the first line on file. You can also use Docker with the instruction on my README: https://github.com/jhvst/nix-config (however, kexec will not likely work, read more how to run it later)
Back to elaborating on the Nix file from the gaming perspective. First, we have the overlays. These are like patches to the packages, and really useful for gaming because it allows building important packages like mesa from the source tip. This is particularly useful when new games or GPUs are released. Same thing for wayland: Nvidia and its proprietary drivers need some patching, but it's possible to get wayland (and sway) to work this way.
Then, I have taken the reproducibility of Nix to a next step in my opinion, and made the system stateless. This means that it runs from the RAM. It is easy to create installation media like kernel, initrd, and rootfs because you have all the steps to create the distribution. This means that here, Nix works as a meta-distro like Gentoo, on top of which you develop your own. Running from the RAM means that theoretically, if you have a working config, and two people with different hardware runs it, then they should have the same experience. If you look at ProtonDB, you often find that some people claim that game X works on their machine with drivers and mesa of Y and Z, but there is no way to copy their configurations because it's certain that the user has made some stateful changes which they have forgotten hence left undocumented, which is the reason it works for them. If everyone would be using Nix, you could reproduce their system and possibly fix your own, but this is not tractable with most OSs.
If you like to test my changes, you can read more about my approach here: https://github.com/NixOS/nixpkgs/pull/203750
For testing I distribute Nvidia as documented here: https://github.com/jhvst/jhvst.github.io/blob/main/ramdisk.m...
However, I have developed it bit further: if you manage to get into an iPXE shell, you can write `boot -a http://boot.ponkila.com/menu.ipxe`, then select the second option which is Nvidia (proprietary drivers), and with some waiting you will get into a shell prompt to which you can write `sway --unsupported-gpu`, which will launch sway. Cmd+Enter opens a prompt to which you can write `steam`, which will open Steam. Then, you have to mount some drive on another shell with `mount`, and add this as a Steam library via Steam's UI. Then you can play games. I use this on AMD and I have been very happy.
To get iPXE, the easy option is to go along with https://netboot.xyz. You will find the `iPXE shell` option here to which to write the boot option from the previous paragraph.
I also added AMD to the iPXE menu for whomever decides to test it. Sway is launched by writing `sway`. Steam should be started with `AMD_VULKAN_ICD="RADV" VK_ICD_FILENAMES="/run/opengl/driver/share/vulkan/icd.d/radeon_icd.x86_64.json" steam` to use the faster RADV driver.
Also setting Coolbits doesn't seem to work either on my end, which means no overclocking support for the Nvidia GPU (if that's something you care about).
NixOS, just like any other OS, can have you walking down the familiar caverns of, "getting the thing to work that this system isn't designed to accommodate well."
But this time is different: you can start over fresh at any time.
This is really the situation where NixOS shines the most. No more, "wondering what you installed where when you were trying to get that over program working the other day." No more, "did I just do the steps in the wrong order?"
It's unbreakable. Your OS is guaranteed to feel like a fresh install. Forever. Because it can't be anything else.
I don't have a laptop like that anymore, but check the NixOS manual and NixOS.wiki, and ask around if you get stuck!
(When I last used it, Bumblebee was the best option and worked well, but these days, native PRIME offloading should also work fine and it's what I would prefer.)
As for Steam, just add
programs.steam.enable = true;
to your config. Works great!(If you're accustomed to Flatpak Steam, you can alternatively enable Flatpak and just install Steam that way, like you would on your existing distro.)
I think is easier to see this with what is their main strength: A declarative/reproducible OS setup. Is AMAZING for server deployment (like what you put in a docker file but that not mutate after it).
But I don't think will be so nice for day to day use. That is where a mutation OS is easier.
Fwiw the best summary of "should I use NixOS" is https://news.ycombinator.com/item?id=33679621
Also since things are declarative, that means things like e.g. updating bash aliases has additional friction vs the traditional way of editing the file directly.
Additional friction (not much imo), but you will actually be able to move that bash plugin that does that thing you didn’t even realize were not available in a vanilla shell.