I'm trying to write a shell.nix
to have a stable environment for doing web development in a project. I'd like to use this so that I don't have to write nix-shell -p nodejs_22 --command "yarn dev"
. However, I don't see a way to specify this in the shell.nix
file.
Here's what I came up with:
{ pkgs ? import <nixpkgs> {} }:
let lib = import <nixpkgs/lib>;
in pkgs.mkShell {
packages = with pkgs; [
nodejs_22 yarn
];
shellHook = ''
export PATH="${pkgs.nodejs_22.out}/bin:$PATH"
yarn dev
'';
}
The problem here is that shellHook
is not really meant to do this. It's meant for initialization purposes. When I CTRL+C (SIGINT) on the node process, it drops me into bash, inside the nix shell. However, I want it to just exit entirely and go back to the shell before nix-shell
was run.
How can I specify the --command
argument inside the shell.nix
file? It it's not possible, it's kind of pointless to me since I could just create a shell script with the full nix-shell command instead.
Using trap - SIGINT
, trap "exit 130" INT
and variations (including using job control) did not help.
I'm trying to write a shell.nix
to have a stable environment for doing web development in a project. I'd like to use this so that I don't have to write nix-shell -p nodejs_22 --command "yarn dev"
. However, I don't see a way to specify this in the shell.nix
file.
Here's what I came up with:
{ pkgs ? import <nixpkgs> {} }:
let lib = import <nixpkgs/lib>;
in pkgs.mkShell {
packages = with pkgs; [
nodejs_22 yarn
];
shellHook = ''
export PATH="${pkgs.nodejs_22.out}/bin:$PATH"
yarn dev
'';
}
The problem here is that shellHook
is not really meant to do this. It's meant for initialization purposes. When I CTRL+C (SIGINT) on the node process, it drops me into bash, inside the nix shell. However, I want it to just exit entirely and go back to the shell before nix-shell
was run.
How can I specify the --command
argument inside the shell.nix
file? It it's not possible, it's kind of pointless to me since I could just create a shell script with the full nix-shell command instead.
Using trap - SIGINT
, trap "exit 130" INT
and variations (including using job control) did not help.
2 Answers
Reset to default 1As you've discovered, nix-shell
isn't really meant for this. If you really insist on this way of running your dev command, then you need an exec
to replace the bash process running your shellHook
with yarn itself:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = [
pkgs.nodejs_22
pkgs.yarn
];
shellHook = "exec yarn dev";
}
This way, a Ctrl+C should not drop you into the shell inside nix-shell
but directly exit.
The solution is to add exit 0
at the end of your shellHook
, but I went ahead and made some other improvements as well:
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = [
pkgs.nodejs_22 pkgs.yarn
];
shellHook = ''
set -e
yarn dev
exit 0
'';
}
Disclaimer: I'm not familiar with Node.js and Yarn, and there might be a better way to set up a Node.js environment in Nix.