{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
  };
  outputs = {
    nixpkgs,
    self,
    ...
  }: let
    systems = [
      "x86_64-linux"
      "aarch64-linux"
      "x86_64-darwin"
      "aarch64-darwin"
    ];
    forAllSystems = f:
      nixpkgs.lib.genAttrs systems (
        system: let
          pkgs = import nixpkgs {inherit system;};
        in
          f {
            inherit pkgs;
            inherit (pkgs) lib;
          }
      );
  in {
    devShells = forAllSystems ({pkgs, ...}: {
      default = with pkgs; let
        # only bump toolchain versions here
        go = go_1_25;
        nodejs = nodejs_24;
        python3 = python312;

        # Platform-specific dependencies
        linuxOnlyInputs = lib.optionals pkgs.stdenv.isLinux [
          glibc.static
        ];

        linuxOnlyEnv = lib.optionalAttrs pkgs.stdenv.isLinux {
          CFLAGS = "-I${glibc.static.dev}/include";
          LDFLAGS = "-L ${glibc.static}/lib";
        };
      in
        pkgs.mkShell {
          buildInputs =
            [
              # generic
              git
              git-lfs
              gnumake
              gnused
              gnutar
              gzip
              zip

              # frontend
              nodejs

              # linting
              python3
              poetry

              # backend
              go
              gofumpt
              sqlite
            ]
            ++ linuxOnlyInputs;

          GO = "${go}/bin/go";
          GOROOT = "${go}/share/go";

          TAGS = "sqlite sqlite_unlock_notify";
          STATIC = "true";
        }
        // linuxOnlyEnv;
    });
    packages = forAllSystems ({
      pkgs,
      lib,
      ...
    }: let
      src = lib.cleanSource ./.;
      version = "1.25.0-rc0-loreddev.0";
    in {
      default = self.packages.${pkgs.system}.gitea;
      dev = let
        pkg = self.packages.${pkgs.system}.default;
      in
        pkgs.symlinkJoin {
          inherit (pkg) pname name meta;
          version = "${pkg.version}.dev";
          paths = [pkg pkgs.makeWrapper];
          postFixup = ''
            wrapProgram $out/bin/gitea \
              --set GITEA_RUN_MODE "dev"
          '';
        };
      /*
      These package functions below have code copied from NixOS nixpkgs's repostiory,
      and can be located at
      <https://github.com/NixOS/nixpkgs/blob/b2a3852bd078e68dd2b3dfa8c00c67af1f0a7d20/pkgs/by-name/gi/gitea/package.nix>

      The original code is licensed under the MIT License (SPDX-License-Identifier: MIT),
      which a copy of the copyright notice and license can be found at
      <https://github.com/NixOS/nixpkgs/blob/b2a3852bd078e68dd2b3dfa8c00c67af1f0a7d20/COPYING>
      and below:

      Copyright (c) 2003-2025 Eelco Dolstra and the Nixpkgs/NixOS contributors

      Permission is hereby granted, free of charge, to any person obtaining
      a copy of this software and associated documentation files (the
      "Software"), to deal in the Software without restriction, including
      without limitation the rights to use, copy, modify, merge, publish,
      distribute, sublicense, and/or sell copies of the Software, and to
      permit persons to whom the Software is furnished to do so, subject to
      the following conditions:

      The above copyright notice and this permission notice shall be
      included in all copies or substantial portions of the Software.

      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
      LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
      OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
      WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      */
      gitea-frontend = let
        pnpm = pkgs.pnpm_10;
      in
        pkgs.stdenv.mkDerivation {
          pname = "gitea-frontend";
          inherit src version;

          buildInputs = [pkgs.nodejs pnpm.configHook pkgs.gnumake];

          buildPhase = ''
            pnpm install --frozen-lockfile
            BROWSERSLIST_IGNORE_OLD_DATA=true make frontend
          '';

          installPhase = ''
            mkdir -p $out
            cp -R public $out/
          '';

          pnpmDeps = pnpm.fetchDeps {
            inherit (self.packages.${pkgs.system}.gitea-frontend) pname src version;
            fetcherVersion = 2;
            hash = "sha256-0p7P68BvO3hv0utUbnPpHSpGLlV7F9HHmOITvJAb/ww=";
          };
        };
      gitea = pkgs.callPackage (
        {
          lib,
          buildGo125Module,
          fetchFromGitHub,
          makeWrapper,
          git,
          bash,
          coreutils,
          compressDrvWeb,
          gitea,
          gzip,
          openssh,
          sqliteSupport ? true,
          nixosTests,
        }:
          buildGo125Module rec {
            pname = "gitea";
            inherit src version;

            proxyVendor = true;

            vendorHash = "sha256-S0hnmPzLPTw+uLelOkVKz/MuUD00eDolb+DqtItKft8=";

            outputs = [
              "out"
              "data"
            ];

            patches = [
              (pkgs.writeText "static-root-path.patch" ''
                diff --git a/modules/setting/server.go b/modules/setting/server.go
                index 183906268..fa02e8915 100644
                --- a/modules/setting/server.go
                +++ b/modules/setting/server.go
                @@ -319,7 +319,7 @@ func loadServerFrom(rootCfg ConfigProvider) {
                 	OfflineMode = sec.Key("OFFLINE_MODE").MustBool()
                 	Log.DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool()
                 	if len(StaticRootPath) == 0 {
                -		StaticRootPath = AppWorkPath
                +		StaticRootPath = "@data@"
                 	}
                 	StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(StaticRootPath)
                 	StaticCacheTime = sec.Key("STATIC_CACHE_TIME").MustDuration(6 * time.Hour)
              '')
            ];

            # go-modules derivation doesn't provide $data
            # so we need to wait until it is built, and then
            # at that time we can then apply the substituteInPlace
            overrideModAttrs = _: {postPatch = null;};

            postPatch = ''
              substituteInPlace modules/setting/server.go --subst-var data
            '';

            subPackages = [
              "."
              "contrib/environment-to-ini"
            ];

            nativeBuildInputs = [makeWrapper];

            tags = lib.optionals sqliteSupport [
              "sqlite"
              "sqlite_unlock_notify"
            ];

            ldflags = [
              "-s"
              "-w"
              "-X main.Version=${version}"
              "-X 'main.Tags=${lib.concatStringsSep " " tags}'"
            ];

            postInstall = ''
              mkdir $data
              ln -s ${self.packages.${pkgs.system}.gitea-frontend}/public $data/public
              cp -R ./{templates,options} $data
              mkdir -p $out
              cp -R ./options/locale $out/locale

              wrapProgram $out/bin/gitea \
                --prefix PATH : ${
                lib.makeBinPath [
                  bash
                  coreutils
                  git
                  gzip
                  openssh
                ]
              }
            '';

            passthru = {
              data-compressed =
                lib.warn "gitea.passthru.data-compressed is deprecated. Use \"compressDrvWeb gitea.data\"."
                (compressDrvWeb gitea.data {});

              tests = nixosTests.gitea;
            };

            meta = with lib; {
              description = "Git with a cup of tea";
              homepage = "https://about.gitea.com";
              license = licenses.mit;
              maintainers = with maintainers; [
                guz013
                techknowlogick
                SuperSandro2000
              ];
              mainProgram = "gitea";
            };
          }
      ) {};
    });
  };
}
