Astro with nix

Note: flakes are still an “experimental” (but recommended) feature of nix. In order to use them you will need to enable them. Write this line to ~/.config/nix/nix.conf:

experimental-features = nix-command flakes

This is the nix flake that powers this site.

Every flake has a description, some inputs, and some outputs.

In this case we have pretty much just the basic inputs - nixpkgs (the main repository of nix-hosted software) and flake-utils, which (almost) every flake uses.

There are two outputs:

  • A devshell with locked versions of npm, pnpm, and vercel
  • A default task which builds this site
flake.nix
{
  description = "Nix by Example";
 
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };
 
  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = nixpkgs.legacyPackages.${system};
        nodejs = pkgs.nodejs_23;
        pnpm = pkgs.pnpm_9;
      in
      {
        devShells.default = pkgs.mkShell {
          buildInputs = with pkgs; [
            nodejs
            pnpm
            nodePackages_latest.vercel
          ];
 
          shellHook = ''
            export PATH="$PWD/node_modules/.bin:$PATH"
          '';
        };
 
        packages.default = pkgs.stdenv.mkDerivation (finalAttrs: {
          pname = "astro-site";
          version = "0.0.1";
          src = ./.;
 
          nativeBuildInputs = [
            nodejs
            pnpm.configHook
          ];
 
          pnpmDeps = pnpm.fetchDeps {
            inherit (finalAttrs) pname version src;
            hash = "sha256-1id+voa1Bil+2YUPa7kMwf1YLCZ2lT1Fp2S31pD8UyY=";
          };
 
          buildPhase = ''
            pnpm run build
          '';
 
          installPhase = ''
            cp -r dist $out
          '';
        });
 
        formatter = pkgs.nixpkgs-fmt;
      });
}

Running nix develop will start a shell with all of our pinned dependencies.

$ nix develop
$ which vercel
/nix/store/lk5pgp4lqbymns1j0dci57kg9dr9in4x-vercel-41.1.4/bin/vercel

Running nix build will build our static site into the result directory.

 $ tree result/
result/
├── 404.html
├── _astro
│   ├── about.B7NnR3ga.css
│   └── client.CZXlMYiT.js
├── about
│   └── index.html
├── android-chrome-192x192.png
├── android-chrome-512x512.png
├── apple-touch-icon.png
├── examples
│   ├── 0
│   │   └── index.html
│   └── 1
│       └── index.html
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
├── index.html
└── site.webmanifest
 
6 directories, 14 files