{
  description = "Home Manager configuration of julian";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.11";
    systems.url = "github:nix-systems/default-linux";
    nixos-hardware.url = "github:nixos/nixos-hardware";
    impermanence.url = "github:nix-community/impermanence";
    nix-colors.url = "github:misterio77/nix-colors";
    deploy-rs.url = "github:serokell/deploy-rs";

    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    sops-nix = {
      url = "github:Mic92/sops-nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    nix-gl = {
      url = "github:nix-community/nixgl";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    disko = {
      url = "github:nix-community/disko";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    # Various flakes
    alacritty-theme = {
      url = "github:alacritty/alacritty-theme";
      flake = false;
    };
    yazi-flavors = {
      url = "github:yazi-rs/flavors";
      flake = false;
    };
    nixvim = {
      url = "github:nix-community/nixvim";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    nix-matlab = {
      url = "gitlab:doronbehar/nix-matlab";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    # My projects
    sheet-organizer = {
      url = "git+https://gitlab.julian-mutter.de/julian/sheet-organizer";
      inputs.nixpkgs.follows = "nixpkgs";
    };
    music-reader = {
      url = "git+https://gitlab.julian-mutter.de/julian/music-reader";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = {
    self,
    nixpkgs,
    home-manager,
    systems,
    ...
  } @ inputs: let
    inherit (self) outputs;
    lib = nixpkgs.lib // home-manager.lib;
    forEachSystem = f: lib.genAttrs (import systems) (system: f pkgsFor.${system});
    pkgsFor = lib.genAttrs (import systems) (
      system:
        import nixpkgs {
          inherit system;
          config.allowUnfree = true;
          config.permittedInsecurePackages = [
            "olm-3.2.16"
          ];
          warn-dirty = false;
        }
    );
  in {
    inherit lib;

    nixosModules = import ./modules/nixos;
    homeManagerModules = import ./modules/home-manager;

    overlays = import ./overlays {inherit inputs outputs;};
    # hydraJobs = import ./hydra.nix { inherit inputs outputs; }; # TODO add hydra jobs here?

    packages = forEachSystem (pkgs: import ./pkgs {inherit pkgs;});
    devShells = forEachSystem (pkgs: import ./shell.nix {inherit pkgs;});
    formatter = forEachSystem (pkgs: pkgs.alejandra);

    nixosConfigurations = {
      # Main laptop
      aspi = lib.nixosSystem {
        modules = [./hosts/aspi];
        specialArgs = {
          inherit inputs outputs;
        };
      };
      # Piano raspberry pi
      pianonix = lib.nixosSystem {
        modules = [./hosts/pianonix];
        specialArgs = {
          inherit inputs outputs;
        };
      };
      kardorf = lib.nixosSystem {
        modules = [./hosts/kardorf];
        specialArgs = {
          inherit inputs outputs;
        };
      };
      builder = lib.nixosSystem {
        modules = [./hosts/builder];
        specialArgs = {
          inherit inputs outputs;
        };
      };
    };

    # Standalone HM
    homeConfigurations = {
      # Main laptop
      "julian@aspi" = lib.homeManagerConfiguration {
        modules = [
          ./homes/julian/aspi.nix
          ./homes/julian/hm-standalone-config.nix
        ];
        pkgs = pkgsFor.x86_64-linux;
        extraSpecialArgs = {
          inherit inputs outputs;
        };
      };
      # Media server (RPi)
      "julian@pianonix" = lib.homeManagerConfiguration {
        modules = [
          ./homes/julian/pianonix.nix
          ./homes/julian/hm-standalone-config.nix
        ];
        pkgs = pkgsFor.aarch64-linux;
        extraSpecialArgs = {
          inherit inputs outputs;
        };
      };
      "julian@kardorf" = lib.homeManagerConfiguration {
        modules = [
          ./homes/julian/kardorf.nix
          ./homes/julian/hm-standalone-config.nix
        ];
        pkgs = pkgsFor.x86_64-linux;
        extraSpecialArgs = {
          inherit inputs outputs;
        };
      };
      "julian@v3ms" = lib.homeManagerConfiguration {
        modules = [
          ./homes/julian/v3ms
          ./homes/julian/hm-standalone-config.nix
        ];
        pkgs = pkgsFor.x86_64-linux;
        extraSpecialArgs = {
          inherit inputs outputs;
        };
      };
    };

    # deploy-rs node configuration
    deploy.nodes = {
      pianonix = {
        hostname = "pianonix.local";
        profiles.system = {
          sshUser = "root";
          user = "root";
          path = inputs.deploy-rs.lib.aarch64-linux.activate.nixos self.nixosConfigurations.pianonix;
          confirmTimeout = 90; # default: 30s; raspberrypi takes a little longer restarting services
        };
      };

      builder = {
        hostname = "builder.julian-mutter.de";
        profiles.system = {
          sshUser = "root";
          user = "root";
          path = inputs.deploy-rs.lib.x86_64-linux.activate.nixos self.nixosConfigurations.builder;
          remoteBuild = true;
        };
      };
    };
  };
}