{
  description = "Jet Pham's personal website";
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    rust-overlay.url = "github:oxalica/rust-overlay";
    flake-utils.url = "github:numtide/flake-utils";
    agenix.url = "github:ryantm/agenix";
    agenix.inputs.nixpkgs.follows = "nixpkgs";
  };
  outputs =
    {
      self,
      nixpkgs,
      rust-overlay,
      flake-utils,
      agenix,
    }:
    (flake-utils.lib.eachDefaultSystem (
      system:
      let
        overlays = [ (import rust-overlay) ];
        pkgs = import nixpkgs { inherit system overlays; };
        agenixPkg = agenix.packages.${system}.default;
        rustToolchain = pkgs.rust-bin.selectLatestNightlyWith (
          toolchain:
          toolchain.default.override {
            extensions = [ "rust-src" ];
            targets = [ "wasm32-unknown-unknown" ];
          }
        );
        rustPlatform = pkgs.makeRustPlatform {
          cargo = rustToolchain;
          rustc = rustToolchain;
        };

        cgol-wasm = rustPlatform.buildRustPackage {
          pname = "cgol-wasm";
          version = "0.1.0";
          src = ./cgol;
          cargoLock.lockFile = ./cgol/Cargo.lock;
          doCheck = false;

          nativeBuildInputs = [
            pkgs.wasm-bindgen-cli
            pkgs.binaryen
          ];

          buildPhase = ''
            runHook preBuild
            cargo build --release --frozen --target wasm32-unknown-unknown
            wasm-bindgen --target web --out-dir pkg target/wasm32-unknown-unknown/release/cgol.wasm
            wasm-opt pkg/cgol_bg.wasm -o pkg/cgol_bg.wasm -O4 \
              --enable-bulk-memory --enable-nontrapping-float-to-int \
              --enable-sign-ext --low-memory-unused --converge
            runHook postBuild
          '';

          installPhase = ''
            runHook preInstall
            mkdir -p $out
            cp pkg/cgol_bg.wasm $out/
            cp pkg/cgol.js $out/
            cp pkg/cgol.d.ts $out/
            cp pkg/cgol_bg.wasm.d.ts $out/ 2>/dev/null || true
            cat > $out/package.json <<'EOF'
            {
              "name": "cgol",
              "type": "module",
              "version": "0.1.0",
              "files": ["cgol_bg.wasm", "cgol.js", "cgol.d.ts"],
              "main": "cgol.js",
              "types": "cgol.d.ts",
              "sideEffects": ["./snippets/*"]
            }
            EOF
            runHook postInstall
          '';
        };

        # Stage 2: Build the website with npm
        website = pkgs.buildNpmPackage {
          pname = "jet-website";
          version = "0.1.0";
          src = pkgs.lib.cleanSource ./.;
          npmDepsHash = "sha256-O4ZUSYyVWOxP15saIadsaZuRO47Y0AvsL4pwvo5b76U=";

          # Inject the Nix-built WASM before npm install resolves file: dep
          postPatch = ''
            mkdir -p cgol/pkg
            cp -r ${cgol-wasm}/* cgol/pkg/
          '';

          installPhase = ''
            runHook preInstall
            mkdir -p $out
            cp -r dist/* $out/
            runHook postInstall
          '';
        };
        qa-api = pkgs.rustPlatform.buildRustPackage {
          pname = "jetpham-qa-api";
          version = "0.1.0";
          src = ./api;
          cargoHash = "sha256-mAQUSA5S3uCCo4RbWVgzMMPDjVoSTcJCFdFOx9ZaxQo=";
          nativeBuildInputs = [ pkgs.pkg-config ];
          buildInputs = [ pkgs.openssl ];
        };

      in
      {
        packages = {
          default = website;
          cgol-wasm = cgol-wasm;
          inherit qa-api;
        };
        devShells.default = pkgs.mkShell {
          buildInputs = with pkgs; [
            nodejs
            git
            curl
            openssl
            agenixPkg
            typescript-language-server
            pkg-config
            wasm-pack
            binaryen
            rustToolchain
          ];
        };
      }
    ))
    // {
      nixosModules.default = import ./module.nix self;
    };
}
