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

    poetry2nix.url = "github:nix-community/poetry2nix";
    poetry2nix.inputs.nixpkgs.follows = "nixpkgs";
    poetry2nix.inputs.flake-utils.follows = "flake-utils";

    wd2.url = "git+https://git.pleshevski.ru/pleshevskiy/wd2";
    wd2.inputs.nixpkgs.follows = "nixpkgs";
    wd2.inputs.flake-utils.follows = "flake-utils";

    nixpkgs_volar.url = "github:ehllie/nixpkgs/volar";
  };

  outputs = { nixpkgs, flake-utils, poetry2nix, ... } @ inputs:
    let
      inherit (builtins) listToAttrs mapAttrs;

      allPackageNames = [ "d2" "d2plugin-tala" "d2full" "wd2" "fawltydeps" "volar" ];
      mkAllPackages = pkgs':
        let
          d2-unwrapped = pkgs'.callPackage ./pkgs/d2/d2-unwrapped.nix { };
          d2plugin-tala = pkgs'.callPackage ./pkgs/d2/d2plugin-tala.nix { };
          d2 = pkgs'.callPackage ./pkgs/d2 {
            inherit d2-unwrapped d2plugin-tala;
          };
        in
        {
          inherit d2 d2plugin-tala;
          d2-full = d2.override { withTala = true; };

          wd2 = pkgs'.callPackage "${inputs.wd2}/wd2.nix" { inherit d2; };

          fawltydeps = pkgs'.callPackage ./pkgs/fawltydeps { };

          # Temporary workaround to use volar language server for vue
          #
          # Remove when the following PR will be merged
          # https://github.com/NixOS/nixpkgs/pull/190921
          volar = inputs.nixpkgs_volar.legacyPackages.${pkgs'.system}.nodePackages.volar;
        };

      mkApp = drv:
        let
          inherit (builtins) head split;
          pname = head (split "-" drv.name);
        in
        flake-utils.lib.mkApp
          {
            inherit drv;
            name = if pname == "volar" then "vue-language-server" else pname;
          };
      mkOverlay = name:
        final: prev:
          final.filterAttrs (n: v: n == name) (mkAllPackages prev)
          // { poetry2nix = nixpkgs.legacyPackages.${final.system}.poetry2nix; };
    in
    {
      overlays = (listToAttrs
        (map
          (name: { inherit name; value = mkOverlay name; })
          allPackageNames
        )
      ) // {
        all = final: prev:
          mkAllPackages prev
          // { poetry2nix = nixpkgs.legacyPackages.${final.system}.poetry2nix; };
      };
    }
    // flake-utils.lib.eachDefaultSystem (system:
      let
        overlays = [ poetry2nix.overlay ];
        pkgs = import nixpkgs { inherit system overlays; };
        packages = mkAllPackages pkgs;
      in
      {
        check = packages;

        inherit packages;
        apps = mapAttrs (name: mkApp) packages;
      });
}