{
  description = "Home Manager configuration of julian";

  inputs = rec {
    nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.11";
    nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";

    nixpkgs = nixpkgs-stable;

    deploy-rs.url = "github:serokell/deploy-rs";

    nixos-hardware.url = "github:NixOS/nixos-hardware/master";

    home-manager = {
      url = "github:nix-community/home-manager/release-24.11";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    snowfall-lib = {
      url = "github:snowfallorg/lib";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    disko = {
      url = "github:nix-community/disko";
      inputs.nixpkgs.follows = "nixpkgs";
    };

    alacritty-theme = {
      url = "github:alacritty/alacritty-theme";
      flake = false;
    };

    yazi-flavors = {
      url = "github:yazi-rs/flavors";
      flake = false;
    };

    nixvim = {
      url = "github:nix-community/nixvim/nixos-24.11";
      # If using a stable channel you can use `url = "github:nix-community/nixvim/nixos-<version>"`
      inputs.nixpkgs.follows = "nixpkgs";
    };

    nix-matlab.url = "gitlab:doronbehar/nix-matlab";
    nix-matlab.inputs.nixpkgs.follows = "nixpkgs";

    sops-nix.url = "github:Mic92/sops-nix";
    sops-nix.inputs.nixpkgs.follows = "nixpkgs";

    hyprland.url = "github:hyprwm/Hyprland?submodules=1";
    # hyprland.inputs.nixpkgs.follows = "nixpkgs";

    hyprland-plugins = {
      url = "github:hyprwm/hyprland-plugins";
      inputs.hyprland.follows = "hyprland";
    };

    nix-colors.url = "github:Misterio77/nix-colors";

    nix-topology.url = "github:oddlama/nix-topology";
    nix-topology.inputs.nixpkgs.follows = "nixpkgs";

    nix-ld.url = "github:Mic92/nix-ld";
    nix-ld.inputs.nixpkgs.follows = "nixpkgs";

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

    music-reader.url = "git+https://gitlab.julian-mutter.de/julian/music-reader";
    music-reader.inputs.nixpkgs.follows = "nixpkgs";
  };

  outputs =
    inputs:
    let
      snowfallOutputs = inputs.snowfall-lib.mkFlake {
        inherit inputs;
        # Must always be ./.
        src = ./.;

        # Add overlays for the `nixpkgs` channel.
        overlays = with inputs; [
          nix-matlab.overlay
          nix-topology.overlays.default
        ];

        snowfall = {
          # The root of the snowfall config
          root = ./.;
          # lib, package and overlay namespace
          namespace = "frajul"; # defaults to "internal"

          meta = {
            name = "Julian's dotfiles";
            title = "Julian's dotfiles";
          };
        };

        # The attribute set specified here will be passed directly to NixPkgs when
        # instantiating the package set.
        channels-config = {
          # Allow unfree packages.
          allowUnfree = true;
          nvidia.acceptLicense = true;

          # Allow certain insecure packages
          permittedInsecurePackages = [ "olm-3.2.16" ];
        };

        systems.modules.nixos = with inputs; [
          nix-topology.nixosModules.default
          sops-nix.nixosModules.sops
          disko.nixosModules.disko
        ];
        systems.hosts.pianonix.modules = with inputs; [ nixos-hardware.nixosModules.raspberry-pi-4 ];

        # topology =
        #   with inputs;
        #   let
        #     host = self.nixosConfigurations.${builtins.head (builtins.attrNames self.nixosConfigurations)};
        #   in
        #   import nix-topology {
        #     inherit (host) pkgs; # Only this package set must include nix-topology.overlays.default
        #     modules = [
        #       (import ./topology { inherit (host) config; })
        #       { inherit (self) nixosConfigurations; }
        #     ];
        #   };
      };
    in
    {
      # 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 inputs.self.nixosConfigurations.pianonix;
          confirmTimeout = 90; # default: 30s; raspberrypi takes a little longer restarting services
        };
      };

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

      hydraJobs = {
        x86_64-linux = {
          aspi = snowfallOutputs.nixosConfigurations.aspi.config.system.build.toplevel;
          builder = snowfallOutputs.nixosConfigurations.builder.config.system.build.toplevel;
          kardorf = snowfallOutputs.nixosConfigurations.kardorf.config.system.build.toplevel;
        };
        aarch64-linux = {
          pianonix = snowfallOutputs.nixosConfigurations.pianonix.config.system.build.toplevel;
        };
      };
    }
    // snowfallOutputs;
}
