{
  description = "My awesome system config";

  inputs = {
    # Nix
    agenix.inputs.nixpkgs.follows = "nixpkgs";
    agenix.url = "github:ryantm/agenix";
    devshell.url = "github:numtide/devshell";
    disko.url = "github:nix-community/disko";
    flake-parts.url = "github:hercules-ci/flake-parts";
    flake-utils.url = "github:numtide/flake-utils";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    home-manager.url = "github:nix-community/home-manager";
    impermanence.url = "github:nix-community/impermanence";
    master.url = "github:nixos/nixpkgs";
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
    pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix";
    stable.url = "github:nixos/nixpkgs/nixos-24.05";
    nur.url = "github:nix-community/NUR";
    nix-index-database.url = "github:Mic92/nix-index-database";
    nix-index-database.inputs.nixpkgs.follows = "nixpkgs";

    # Programs
    nix-super.url = "github:privatevoid-net/nix-super";
    nix-monitored.url = "github:ners/nix-monitored";
    nix-monitored.inputs.nixpkgs.follows = "nixpkgs";
    timers.url = "git+https://gitea.moritzboeh.me/moritz/timers.git";

    # Neovim
    actions-preview-nvim.flake = false;
    actions-preview-nvim.url = "github:aznhe21/actions-preview.nvim";
    neovim-nightly-overlay.url = "github:nix-community/neovim-nightly-overlay";
    nix-lazy-nvim.url = "git+https://git.moritzboeh.me/moritz/NixLazy.nvim";
    nvim-lspconfig.flake = false;
    nvim-lspconfig.url = "github:neovim/nvim-lspconfig";
    smartcolumn-nvim.flake = false;
    smartcolumn-nvim.url = "github:m4xshen/smartcolumn.nvim";
    telekasten-nvim.flake = false;
    telekasten-nvim.url = "github:renerocksai/telekasten.nvim";
    neotest-python.flake = false;
    neotest-python.url = "github:MoritzBoehme/neotest-python/fix-runtimepath-search";
    gen-nvim.flake = false;
    gen-nvim.url = "github:David-Kunz/gen.nvim";
    hawtkeys-nvim.flake = false;
    hawtkeys-nvim.url = "github:tris203/hawtkeys.nvim";
    none-ls-shellcheck-nvim.flake = false;
    none-ls-shellcheck-nvim.url = "github:gbprod/none-ls-shellcheck.nvim";
    cmp-vimtex.flake = false;
    cmp-vimtex.url = "github:micangl/cmp-vimtex";

    # river
    river.url = "git+https://github.com/riverwm/river?submodules=1";
    river.flake = false;

    # Hyprland
    hypr-contrib.url = "github:hyprwm/contrib";
    hyprland = {
      type = "git";
      url = "https://github.com/hyprwm/Hyprland";
      submodules = true;
    };

    # Laptop
    asus-touchpad-numpad-driver.url = "github:MoritzBoehme/asus-touchpad-numpad-driver/german-layout";
    asus-touchpad-numpad-driver.flake = false;

    # Firefox user.js
    arkenfox-userjs.url = "github:arkenfox/user.js";
    arkenfox-userjs.flake = false;
  };

  outputs = inputs@{ self, flake-parts, ... }:
    flake-parts.lib.mkFlake { inherit inputs; } {
      debug = true; # NOTE: for nixd
      imports = [
        inputs.pre-commit-hooks.flakeModule
        inputs.devshell.flakeModule
      ];

      systems = [ "x86_64-linux" ];
      perSystem = { config, self', inputs', pkgs, system, ... }: {
        devshells.default = {
          devshell.startup.pre-commit-hook.text = config.pre-commit.installationScript;
          commands = [
            {
              name = "agenix";
              help = "wrapper around agenix";
              command = ''
                sudo EDITOR="${pkgs.lib.getExe pkgs.vim}" ${pkgs.lib.getExe' inputs'.agenix.packages.default "agenix"} --identity /etc/ssh/ssh_host_ed25519_key "$@"
              '';
            }
            {
              name = "build";
              help = "use nom to build system";
              command =
                ''
                  nom build --no-link ".#nixosConfigurations.$(hostname).config.system.build.toplevel" $@
                '';
            }
            {
              name = "apply";
              help = "wrapper for nixos-rebuild switch";
              command = "sudo nixos-rebuild switch --flake . $@";
            }
            {
              name = "test";
              help = "wrapper for nixos-rebuild switch";
              command = "sudo nixos-rebuild test --flake . $@";
            }
            {
              name = "boot";
              help = "wrapper for nixos-rebuild switch";
              command = "sudo nixos-rebuild boot --flake . $@";
            }
          ];
          packages = with pkgs; [
            stylua
            sumneko-lua-language-server
          ];
        };

        pre-commit = {
          check.enable = true;
          settings = {
            hooks = {
              nixpkgs-fmt.enable = true;
              statix.enable = true;
              shellcheck.enable = true;
              stylua.enable = true;
            };
          };
        };

        legacyPackages = pkgs;

      };

      flake = {
        lib = inputs.nixpkgs.lib.extend
          (self: _: { my = import ./lib { lib = self; }; });

        nixosConfigurations = self.lib.my.mapModules
          (path: self.lib.nixosSystem {
            inherit (self) lib;
            specialArgs = {
              inherit inputs self;
            };
            modules =
              [
                ./modules
                {
                  home-manager = {
                    useGlobalPkgs = true;
                    useUserPackages = true;
                    extraSpecialArgs = { inherit inputs self; };
                    sharedModules = [ inputs.nix-lazy-nvim.homeManagerModules.default ];
                  };
                }
                inputs.agenix.nixosModules.age
                inputs.disko.nixosModules.default
                inputs.home-manager.nixosModule
                inputs.impermanence.nixosModules.impermanence
                inputs.nix-index-database.nixosModules.nix-index
                path
              ];
          })
          ./hosts;

        templates = {
          python = {
            description = "Simple poetry shell.nix";
            path = ./templates/python;
          };
          rust = {
            description = "Crane + Fenix flake with mold for faster local builds.";
            path = ./templates/rust;
          };
        };
      };
    };

  nixConfig = {
    extra-substituters = [
      "https://hyprland.cachix.org"
      "https://nix-community.cachix.org"
      "https://pre-commit-hooks.cachix.org"
    ];
    extra-trusted-public-keys = [
      "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
      "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
      "pre-commit-hooks.cachix.org-1:Pkk3Panw5AW24TOv6kz3PvLhlH8puAsJTBbOPmBo7Rc="
    ];
  };
}
