# Difference between nix-shell and "nix run"?

**URL:** https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951
**Category:** Help
**Created:** [May 17, 2019, 12:51am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951 "2019-05-17T00:51:23Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![iwinux](https://discourse.nixos.org/user_avatar/discourse.nixos.org/iwinux/32/603_2.png) [@iwinux](https://discourse.nixos.org/u/iwinux)
#### Post date: [May 17, 2019, 12:51am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/1 "2019-05-17T00:51:23Z")

</div>

I’m trying to define common Nix shells as overlays, but somehow `nix run` refuses to use them.

For example:

```nix
self: super:

{
  go-dev-shell = mkShell {
    buildInputs = with self; [
      delve
      go
      gotools
    ];

    shellHook = ''
      export GO111MODULE=on
      export GOPATH=$HOME/.go
    '';
  };
}

```

`nix-shell -A go-dev-shell '<nixpkgs>'` works fine, but `nix run -f '<nixpkgs>' go-dev-shell` always complains about `This derivation is not meant to be built, aborting`.

From what I’ve learned, `mkShell` is a simple wrapper around `stdenv.mkDerivation` that disables all build phases (see [`pkgs/build-support/mkshell/default.nix`](https://github.com/NixOS/nixpkgs/blob/240ae5eb87b5506f802a4ca16c2b564654f4b9b3/pkgs/build-support/mkshell/default.nix#L33)) - there shouldn’t be any special handling for `mkShell` in `nix-shell`, right?

Therefore I cannot understand what is the difference between `nix-shell` and `nix run` ☹.

---

<div class="post-metadata">

### Author: ![fghibellini](https://discourse.nixos.org/user_avatar/discourse.nixos.org/fghibellini/32/1195_2.png) [@fghibellini](https://discourse.nixos.org/u/fghibellini)
#### Post date: [May 17, 2019, 12:58am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/2 "2019-05-17T00:58:01Z")

</div>

`nix-shell` gives you an environment where the **dependencies** of the supplied expression are available, not the package itself.  
That’s why derivations created with `mkShell` cannot be built.

`nix-shell` has the `-p` flag that behaves as you expected (i.e. provides a shell with the given package). e.g.:

```bash
nix-shell -p gimp --run gimp

```

---

<div class="post-metadata">

### Author: ![iwinux](https://discourse.nixos.org/user_avatar/discourse.nixos.org/iwinux/32/603_2.png) [@iwinux](https://discourse.nixos.org/u/iwinux)
#### Post date: [May 17, 2019, 1:06am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/3 "2019-05-17T01:06:54Z")

</div>

Yeah. I understand that `mkShell` derivation cannot be built. Problem is: how does `nix-shell` treat it differently while `nix run` doesn’t?

Or: I want to replace `nix-shell` with `nix run`. Is that possible?

---

<div class="post-metadata">

### Author: ![fghibellini](https://discourse.nixos.org/user_avatar/discourse.nixos.org/fghibellini/32/1195_2.png) [@fghibellini](https://discourse.nixos.org/u/fghibellini)
#### Post date: [May 17, 2019, 1:14am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/4 "2019-05-17T01:14:56Z")

</div>

> [@iwinux](#):
>
> delve go gotools

`nix-shell -A go-dev-shell '<nixpkgs>'` will run the equivalent of `nix run -f '<nixpkgs>' delve go gotools` + some shell setup.

I see `nix run` for the first time, but from the manual page it would seem that no.

---

<div class="post-metadata">

### Author: ![lilyball](https://discourse.nixos.org/user_avatar/discourse.nixos.org/lilyball/32/939_2.png) [@lilyball](https://discourse.nixos.org/u/lilyball)
#### Post date: [May 17, 2019, 1:50am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/5 "2019-05-17T01:50:27Z")

</div>

`nix-shell` doesn’t build the package itself. I haven’t looked into the details but AIUI it doesn’t run the phases for the derivation, though I think it makes them available as shell functions. `mkShell` disables building by defining a single phase that always aborts. `nix run` does build the derivation and makes it available to the shell. It’s like `nix-shell -p`, which I would assume would abort on a `mkShell` the same way `nix run` does.

---

<div class="post-metadata">

### Author: ![layus](https://discourse.nixos.org/user_avatar/discourse.nixos.org/layus/32/125_2.png) [@layus](https://discourse.nixos.org/u/layus)
#### Post date: [May 17, 2019, 9:00am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/6 "2019-05-17T09:00:14Z")

</div>

**tl;dr** `nix run` is a “new interface”, part of nix 2.0. This new interface has no implementation for the feature from nix-shell that you are looking for.

`nix run pkg1 pkg2` supersedes `nix-shell -p pkg1 pkg2`, but `nix-shell -A pkg` has no equivalent. The magic of `nix-shell -A pkg` is that it goes trough all the dependencies of `pkg` and starts a shell with these packages in the environment.

To reproduce that, you need to be able to extract all the dependencies of a package, which is done in nix-shell (around [here](https://github.com/NixOS/nix/blob/c0559a1d6092b94c7ce46a065d72fc74e4db51dd/src/nix-build/nix-build.cc#L361) and [here](https://github.com/NixOS/nix/blob/c0559a1d6092b94c7ce46a065d72fc74e4db51dd/src/nix-build/nix-build.cc#L408-L411)) but has no equivalent in `nix run` ([here](https://github.com/NixOS/nix/blob/01d07b1e92c298f729a73705907b2987da9a4d0c/src/nix/run.cc)) because it has no extraction logic.

If you want to emulate `nix-shell` with `nix run`, you may consider using `nix run $(nix-build $(nix-store -q --references $(nix-instantiate) | grep ".drv$" | grep -v bash))` which still uses the old interface to obtain the .drv (`nix-instantiate`), to extract the dependencies (`nix-store -q --references`) and to build these .drvs (`nix-build`). The new `nix build` interface does not print the outputs, and therefore cannot be used here. the others have no equivalent.

nix 2.0 interface is still a work in progress, you should stick with nix-shell to get a shell from a derivation seen as an “environment” for that shell.

---

<div class="post-metadata">

### Author: ![maralorn](https://discourse.nixos.org/user_avatar/discourse.nixos.org/maralorn/32/15365_2.png) [@maralorn](https://discourse.nixos.org/u/maralorn)
#### Post date: [May 17, 2019, 7:00pm UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/7 "2019-05-17T19:00:59Z")

</div>

Thanks for that explanation!

Is there the intention to implement something like `nix shell` in nix 2.x or is the plan to keep nix-shell around?

---

<div class="post-metadata">

### Author: ![layus](https://discourse.nixos.org/user_avatar/discourse.nixos.org/layus/32/125_2.png) [@layus](https://discourse.nixos.org/u/layus)
#### Post date: [May 19, 2019, 8:13am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/8 "2019-05-19T08:13:49Z")

</div>

That would be a question for @edolstra, but here is what seems likely to happen from my point of view, which may be very wrong.

nix-shell contains a lot of ad-hoc hacks to setup the environment, and this stuff does not really pertain to nix per se. So I guess there is little chance to see nix-shell ported as-is. More probably, the functionnality will see a large reactoring to move most of the custom hacks into nixpkgs and cleaner, well-defined interfaces.

This is a lot of work, and no-one seems too eager to start working on it as `nix-shell` is still fully supported, maintained, and working as intended.

---

<div class="post-metadata">

### Author: ![qrilka](https://discourse.nixos.org/user_avatar/discourse.nixos.org/qrilka/32/1172_2.png) [@qrilka](https://discourse.nixos.org/u/qrilka)
#### Post date: [April 1, 2020, 8:58pm UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/9 "2020-04-01T20:58:27Z")

</div>

More than 10 months passed since the last reply here - are there any news regarding nix-shell in the new interface? Maybe there is some ticket on the topic?

---

<div class="post-metadata">

### Author: ![toraritte](https://discourse.nixos.org/user_avatar/discourse.nixos.org/toraritte/32/6777_2.png) [@toraritte](https://discourse.nixos.org/u/toraritte)
#### Post date: [May 9, 2021, 3:47pm UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/10 "2021-05-09T15:47:18Z")

</div>

Going to quote @lilyball’s [reply verbatim from another thread](https://discourse.nixos.org/t/the-nix-elevator-pitch/3920/21) because it is highly relevant:

> BTW the “better option” here is `nix run` . `nix-shell -p foo` sets up the environment as it would for building `foo` , so all of `foo` 's dependencies are in your `PATH` and all of the other environment vars are set too (I count 23 env vars containing `NIX` ), but `nix run` produces an environment much more similar to what you’d get if you simply installed the package (e.g. it basically just prefixes your `PATH` with the appropriate directories from the specified package).
> 
> That said, `nix-shell` replaces your normal shell initialization files and `nix run` doesn’t, so depending on how your `.bashrc` is set up you might override the `PATH` . For example with my setup, `echo $PATH` in a `nix run` shell starts the path with `/usr/local/bin` before the nix-provided path value, because my current `.bashrc` unconditionally prefixes my PATH (which I really should fix).

---

<div class="post-metadata">

### Author: ![samuela](https://discourse.nixos.org/user_avatar/discourse.nixos.org/samuela/32/2486_2.png) [@samuela](https://discourse.nixos.org/u/samuela)
#### Post date: [August 30, 2021, 10:00pm UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/11 "2021-08-30T22:00:31Z")

</div>

If I have a `shell.nix` file, I can simply run

```auto
❯ nix-shell
these paths will be fetched (0.05 MiB download, 0.28 MiB unpacked):
  /nix/store/qgbwdnk91rk26b5bkd6qv5r6c2v733kb-bash-interactive-4.4-p23-dev
copying path '/nix/store/qgbwdnk91rk26b5bkd6qv5r6c2v733kb-bash-interactive-4.4-p23-dev' from 'https://cache.nixos.org'...

[nix-shell:~/dev/research/julia/odecontrol]$

```

Can I do something similar with `nix run`? I haven’t been able to make it work:

```auto
❯ nix run
error: opening file '/home/skainswo/dev/research/julia/odecontrol/default.nix': No such file or directory

```

---

<div class="post-metadata">

### Author: ![NobbZ](https://discourse.nixos.org/user_avatar/discourse.nixos.org/nobbz/32/7022_2.png) [@NobbZ](https://discourse.nixos.org/u/NobbZ)
#### Post date: [August 30, 2021, 10:17pm UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/12 "2021-08-30T22:17:51Z")

</div>

`nix` 2.3 or 2.4pre?

For 2.3, no, `run` does _not_ read from a `shell.nix`, as the content of a `shell.nix` is not meant to be built. `run` though builds and then gives the build result in the environment. `nix-shell` and `nix shell` (2.3) though do not build the mentioned derivations, but instead their buildinputs and give those into the environment.

2.4s `run` works completely different from both, and require a flake with applications.

---

<div class="post-metadata">

### Author: ![jonringer](https://discourse.nixos.org/user_avatar/discourse.nixos.org/jonringer/32/1348_2.png) [@jonringer](https://discourse.nixos.org/u/jonringer)
#### Post date: [August 31, 2021, 3:59am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/13 "2021-08-31T03:59:54Z")

</div>

`nix develop` is more similar to that usage, you can also use `nix shell`, but `nix shell` is more similar to `nix-shell -p`

---

<div class="post-metadata">

### Author: ![bhoot](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bhoot/32/28357_2.png) [@bhoot](https://discourse.nixos.org/u/bhoot)
#### Post date: [September 20, 2021, 5:19pm UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/14 "2021-09-20T17:19:12Z")

</div>

What is the difference between `nix shell` and `nix develop`? From `nix --help` for `2.4pre`:

```auto
nix develop - run a bash shell that provides the build environment of a derivation

nix shell - run a shell in which the specified packages are available

```

but I still can’t mentally differentiate between the two, unlike `nix run`, which clearly has a different purpose now - to run nix apps.

---

<div class="post-metadata">

### Author: ![jonringer](https://discourse.nixos.org/user_avatar/discourse.nixos.org/jonringer/32/1348_2.png) [@jonringer](https://discourse.nixos.org/u/jonringer)
#### Post date: [September 20, 2021, 5:56pm UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/15 "2021-09-20T17:56:18Z")

</div>

`nix develop` takes a single derivation, and gives you a shell to make it (all dependencies needed to build it will be exposed in the shell).

`nix shell`, essentially adds packages to the current shell. (Technically forks the shell, and in the child shell will add the packages)

Example:

`nix develop nixpkgs#ripgrep` → You will have rust, pkg-config, and a few other packages added to your shell, but not ripgrep

`nix shell nixpkgs#ripgrep` → You will have access to ripgrep, and nothing else will be added.

---

<div class="post-metadata">

### Author: ![bew](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bew/32/2091_2.png) [@bew](https://discourse.nixos.org/u/bew)
#### Post date: [September 20, 2021, 7:54pm UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/16 "2021-09-20T19:54:38Z")

</div>

> [@jonringer](#):
>
> `nix shell` , essentially adds packages to the current shell.

not really the **current** shell.

I think a better definition would be:  
`nix shell` will start a new shell where all the packages you give it are available to use.

---

<div class="post-metadata">

### Author: ![bhoot](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bhoot/32/28357_2.png) [@bhoot](https://discourse.nixos.org/u/bhoot)
#### Post date: [September 21, 2021, 3:02am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/17 "2021-09-21T03:02:47Z")

</div>

So `nix develop` is analogous to `nix-build` while `nix shell` is analogous to `nix-shell`.

But then there is also `nix build`.

Maybe it’s futile to draw similarities between the old and the new commands, just take them for what they are.

---

<div class="post-metadata">

### Author: ![cdepillabout](https://discourse.nixos.org/user_avatar/discourse.nixos.org/cdepillabout/32/410_2.png) [@cdepillabout](https://discourse.nixos.org/u/cdepillabout)
#### Post date: [September 21, 2021, 5:33am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/18 "2021-09-21T05:33:48Z")

</div>

@jayesh.bhoot I think a better breakdown would look like this:

| use | old command | new command |
| --- | --- | --- |
| start a new shell that has `ripgrep` available | `nix-shell -p ripgrep` | `nix shell nixpkgs#ripgrep` |
| start a new shell that has the dependencies required for building `ripgrep` available (like `gcc` and `rustc`) | `nix-shell -A ripgrep` | `nix develop nixpkgs#ripgrep` |
| build `ripgrep` completely within Nix. Put the resulting binary in a `result/` symlink | `nix-build -A ripgrep` | `nix build nixpkgs#ripgrep` |
| run an application defined in a flake | _nothing similar?_ | `nix run nixpkgs#ripgrep` |

A couple things to keep in mind:

- `nix build`, `nix develop`, and `nix run` have special support for flakes. For instance, if there is a `flake.nix` in the current directory, then:

- You might be able to make the argument that `nix run` is similar to `nix-shell -p ripgrep --run 'ripgrep'`, but this is somewhat of a stretch.

- `nix shell` may be renamed: [Rename 'nix shell' · Issue #4715 · NixOS/nix · GitHub](https://github.com/NixOS/nix/issues/4715)

---

<div class="post-metadata">

### Author: ![bhoot](https://discourse.nixos.org/user_avatar/discourse.nixos.org/bhoot/32/28357_2.png) [@bhoot](https://discourse.nixos.org/u/bhoot)
#### Post date: [September 21, 2021, 6:19am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/20 "2021-09-21T06:19:20Z")

</div>

Thank you. This, combined with [Flakes - NixOS Wiki](https://nixos.wiki/wiki/Flakes#Output_schema), give us a lot of clarity.

The most authoritative page on the `nix` command seems to be [Nix command - NixOS Wiki](https://nixos.wiki/wiki/Nix_command). You should consider putting your response there.

---

<div class="post-metadata">

### Author: ![cdepillabout](https://discourse.nixos.org/user_avatar/discourse.nixos.org/cdepillabout/32/410_2.png) [@cdepillabout](https://discourse.nixos.org/u/cdepillabout)
#### Post date: [September 21, 2021, 8:56am UTC](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951/21 "2021-09-21T08:56:20Z")

</div>

While the wiki does have a lot of good info, I’d recommend you make sure to read through all the man pages for `nix`. By now I think these pages have a lot more info on the new-style Nix commands:

[https://nixos.org/manual/nix/unstable/command-ref/experimental-commands.html](https://nixos.org/manual/nix/unstable/command-ref/experimental-commands.html)

[Next page](https://discourse.nixos.org/t/difference-between-nix-shell-and-nix-run/2951.md?page=2)
