{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs";
  };

  outputs = { self, nixpkgs }:
  let
    system = "x86_64-linux";
    lib = nixpkgs.lib;

    pkgsDir = ./pkgs;

    # `builtins.readDir` returns an attribute set of entries. Use an empty
    # attrset when missing so the type stays consistent during eval.
    entries = if builtins.pathExists pkgsDir then builtins.readDir pkgsDir else {};

    # only subdirectories: filter the entries attribute-set and get the names
    pkgNames = lib.attrNames (lib.filterAttrs (_: t: t == "directory") entries);

    loadPkg = name:
      let
        path = pkgsDir + "/${name}";
        flake = builtins.getFlake (toString path);
      in
        # since all are guaranteed identical shape:
        flake.packages.${system}.default;

    # build final package set
    packages = lib.listToAttrs (builtins.map (name: { inherit name; value = loadPkg name; }) pkgNames);

  in {
    packages.${system} = packages;

    extra = {
      pkgNames = pkgNames;
    };

    overlays.default = final: prev: {
      myPkgs = packages;
    };
  };
}
