{
  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/pianonix ];
          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.aarch64-linux;
          extraSpecialArgs = {
            inherit inputs outputs;
          };
        };
        "julian@v3ms" = lib.homeManagerConfiguration {
          modules = [
            ./homes/julian/v3ms
            ./homes/julian/hm-standalone-config.nix
          ];
          pkgs = pkgsFor.aarch64-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;
          };
        };
      };
    };
}