How to use nix to build a create-react-app project?

Hi,

I am trying to bring nix into a create-react-app project that is the web-frontend of a larger project. Is there any existing tooling to achieve this?

Specifically, how can I write/generate a nix derivation that produces a build directory containing a minified bundle of the project? As described in the quickstart Getting Started | Create React App guide the following create a starting application and creates an optimized build for it:

npx create-react-app my-app
cd my-app
npm run build

How can this be done in nix?

1 Like

In reddit the most up-voted answer was to adapt this that provides a purescript environment to provide a react environment. But I haven’t been able to do so yet.

Edit: fixed markdown links

1 Like
  1. Create a shell.nix file with
    with import <nixpkgs> {};
    stdenv.mkDerivation {
      name = "react-bootstrap-shell";
      buildInputs = with pkgs; [
        nodePackages.create-react-app
        nodejs
        yarn
      ];
    }
    
  2. Run nix-shell shell.nix
  3. And npx away!

Did you ever get this problem?

$ npx create-react-app my-app

Creating a new React app in /home/bbigras2/tmp/test-cra/my-app.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...

yarn add v1.21.1
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.9: The platform "linux" is incompatible with this module.
info "fsevents@1.2.9" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@2.1.2: The platform "linux" is incompatible with this module.
info "fsevents@2.1.2" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning "react-scripts > @typescript-eslint/eslint-plugin > tsutils@3.17.1" has unmet peer dependency "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta".
[4/4] Building fresh packages...
error An unexpected error occurred: "EACCES: permission denied, open '/home/bbigras2/tmp/test-cra/my-app/yarn.lock'".
info If you think this is a bug, please open a bug report with the information provided in "/home/bbigras2/tmp/test-cra/my-app/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

Aborting installation.
  yarnpkg add --exact react react-dom react-scripts cra-template --cwd /home/bbigras2/tmp/test-cra/my-app has failed.

Deleting generated file... node_modules
Deleting generated file... package.json
Deleting generated file... yarn.lock
Done.

I did. It came up when port 8000 was already being used.

I don’t seem to have anything listening on 8000 but thanks for the help.

Yes I am seeing this as well. Did you managed to resolve it @bbigras ?

I have no idea if I did anything to get rid of it, but I don’t have the problem anymore.

I just ran npx create-react-app my-app inside a nix-shell -p nodejs and it was fine.

Thanks @bbigras ! Sorry I replied late - the root cause is that react-create-app (incorrectly I think) assumes the installed software has write permission. See nodePackages.create-react-app doesn't work · Issue #88712 · NixOS/nixpkgs · GitHub

I basically patched it as it worked.

Hi everyone,

I’ve been trying to build my freshly created create-react-app project using nix and this discussion is one of the first threads I hit on Google, but unfortunately, neither the discussion here nor other links I’ve found on Google worked for me out of the box. After some wrestling with nix, nixpkgs and yarn, I’ve finally come up with the following default.nix that works for me when I drop it into my project’s root folder:

let
  nixpkgs = import (builtins.fetchTarball {
    name = "nixpkgs-release-21.11";
    url = "https://github.com/nixos/nixpkgs/archive/cdd6fd92ee2334fe49483bec7b9b64920ba1403a.tar.gz";
    sha256 = "05nb9v77rx0y72zfghi7v1qxb683flx6sgjqlvkk83zb8a8bgn1h";
  }) {};
  inherit (nixpkgs) fetchFromGitHub mkYarnPackage;
  gitignoreSrc = builtins.fetchTarball {
    name = "nixpkgs-release-21.11";
    url = "https://github.com/hercules-ci/gitignore.nix/archive/5b9e0ff9d3b551234b4f3eb3983744fa354b17f1.tar.gz";
    sha256 = "01l4phiqgw9xgaxr6jr456qmww6kzghqrnbc7aiiww3h6db5vw53";
  };
  inherit (import gitignoreSrc { inherit (nixpkgs) lib; }) gitignoreSource;
  spa = (mkYarnPackage {src = gitignoreSource ./.;}).overrideAttrs
    (oldAttrs: let pname = oldAttrs.pname; in {
      doDist = false;
      buildPhase = ''
        runHook preBuild
        shopt -s dotglob

        rm deps/${pname}/node_modules
        mkdir deps/${pname}/node_modules
        pushd deps/${pname}/node_modules
        ln -s ../../../node_modules/* .
        popd
        yarn --offline build
        runHook postBuild
      '';
      installPhase = ''
        runHook preInstall

        mv deps/${pname}/build $out

        runHook postInstall
      '';
    });
in spa

The following worked for me:

{ gitignore, ... }:
{
  pkgs,
  lib,
  stdenv,
  ...
}:
let
  inherit (gitignore.lib) gitignoreSource;
in
(pkgs.buildNpmPackage {
  name = "giveandtake";
  src = gitignoreSource ../client/.;
  npmDepsHash = "sha256-D/9YjHd8e2Ou4VJCEfZMVg70UZs4JgaG2gtPA0pzBJc";
}).overrideAttrs
  (oldAttrs: {
    installPhase = ''
      mv build $out
    '';
  })