{
  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let pkgs = nixpkgs.legacyPackages.${system}; prev = pkgs; in
      {
        # see https://discourse.nixos.org/t/add-python-package-via-overlay/19783/4
        other.pythonPackagesOverlays = (prev.pythonPackagesOverlays or [ ]) ++ [
          (python-final: python-prev: {
            pybars3 = python-final.callPackage nix/pybars3.nix { };
            pymeta3 = python-final.callPackage nix/pymeta3.nix { };
            qrcodegen = python-final.callPackage nix/qrcodegen.nix { };
            svgutils = python-final.callPackage nix/svgutils.nix { };
            pcbnewTransition = python-final.callPackage nix/pcbnewTransition.nix { };
          })
        ];
        other.python3Packages = self.packages.${system}.python3.pkgs;
        packages = with self.other.${system}; rec {
          python3 = prev.python3.override {
            self = python3;
            packageOverrides = prev.lib.composeManyExtensions pythonPackagesOverlays;
          };

          recordmydesktop = pkgs.callPackage nix/recordmydesktop.nix { };
          kikit = python3Packages.callPackage nix/kikit.nix { };
          kiauto = python3Packages.callPackage nix/kiauto.nix { inherit recordmydesktop; };
          kidiff = python3Packages.callPackage nix/kidiff.nix { inherit kiauto; };

          kibot = python3Packages.buildPythonApplication {
            pname = "KiBot";
            version = "2";
            src = pkgs.fetchFromGitHub {
              owner = "INTI-CMNB";
              repo = "KiBot";
              rev = "v2";
              hash = "sha256-ArOKcJLwhLKXNRQIWXzWvMsjC7tJQQoi1kfRHNVdQ+o=";
            };
            propagatedBuildInputs = (with python3Packages; [
              pyaml
              requests
              markdown2
              mistune
              qrcode
              colorama
              numpy
              qrcodegen
              XlsxWriter
              lxml

              lark
              svgutils
            ]) ++ (with pkgs; [
              openscad
              xorg.xorgserver
              xvfb-run
              blender
              git
              imagemagick
              librsvg
              ghostscript
              pandoc
              #helvetica-neue-lt-std
            ]) ++ [
              kikit
              kiauto
              kidiff
            ];

            # Tests will test more features than we need (and thus need more dependencies) so let's skip them.
            doCheck = false;

            #postPatch = ''
            #  #sed -i 's/from .macros import macros, /from .macros import /' kibot/*.py
            #  echo "def macros():" >>kibot/macros.py
            #  echo '  """dummy"""' >>kibot/macros.py
            #  echo '  pass' >>kibot/macros.py
            #'';

            postInstall = ''
              # KiBot seems to have some way of auto-importing stuff and that breaks if there are .pyc files.
              # (ERROR:Make sure you used `--no-compile` if you used pip for installation (kibot - kiplot.py:79))
              rm $out/lib/python*/site-packages/kibot/__pycache__/*.pyc
            '';
          };

          default = kibot;
        };
        apps = rec {
          kikit = flake-utils.lib.mkApp { drv = self.packages.${system}.kikit; };
          kibot = flake-utils.lib.mkApp { drv = self.packages.${system}.kibot; };
          default = kibot;
        };
        devShells.default = with self.packages.${system}; pkgs.mkShell {
          packages = [
            (python3.withPackages (p: [ kibot ]))
            kibot
            pkgs.hello
          ];
        };
      }
    );
}