{
  nixpkgs,
  dream2nix,
  fenix,
  system,
}: {
  server = let
    rust-toolchain = fenix.packages.${system}.stable;
  in
    dream2nix.lib.makeFlakeOutputs {
      systems = [system];
      config.projectRoot = ../server;
      source = ../server;

      packageOverrides = {
        "^.*".set-toolchain.overrideRustToolchain = old: {
          cargo = rust-toolchain.minimalToolchain;
          rustc = rust-toolchain.minimalToolchain;
        };
      };
    }
    // {
      inherit rust-toolchain;
    };

  templates = let
    inherit (nixpkgs.legacyPackages.${system}) runCommandLocal yj;
  in
    dream2nix.lib.makeFlakeOutputs {
      systems = [system];
      config.projectRoot = ../templates;

      # Generate `package.json` from `package.yaml`, since the nodejs
      # ecosystem doesn't support yaml.
      source = runCommandLocal "templates" {nativeBuildInputs = [yj];} ''
        cp -r ${../templates} $out/
        chmod u+w $out
        yj < ${../templates/package.yaml} > $out/package.json
      '';

      packageOverrides = {
        tlaternet = {
          add-build-script = {
            # Dream2nix' built-in install script assumes this is just
            # a usual npm package and will install it in
            # `node_modules`.
            #
            # Parcel will detect this, and completely break all
            # configuration. Furthermore, we don't actually want to
            # install this as if it was an npm library.
            #
            # The easiest way to fix this is just to rename the
            # top-level directory.
            preBuild = ''
              # Rename top-level directory so parcel doesn't think we're in a
              # node_module
              mv ../../node_modules ../../top-level

              # Rewrite $PATH and co. to use the new path.
              export PATH=''${PATH//lib\/node_modules\/.bin/lib\/top-level\/.bin}
              export NODE_PATH=''${NODE_PATH//lib\/node_modules/lib\/top-level}
            '';

            installPhase = ''
              # For some reason, dream2nix builds in the out directory. Don't ask
              # me, I don't know either.

              # First, go to a sane directory and back up our actual build output
              mv dist /build/dist
              cd /build

              # Then, delete everything currently in $out
              chmod -R u+rwx $out
              rm -r $out

              # Finally, actually install our output
              mv dist $out
            '';
          };
        };

        sharp = {
          add-libvips = {
            buildInputs = old:
              old
              ++ (with nixpkgs.legacyPackages.${system}; [
                vips
                pkg-config
              ]);
          };
        };
      };
    };
}
