{
  inputs = {
    crane.url = "github:ipetkov/crane";
    crane.inputs.nixpkgs.follows = "nixpkgs";
    fenix.url = "github:nix-community/fenix";
    fenix.inputs.nixpkgs.follows = "nixpkgs";
    flake-utils.url = "github:numtide/flake-utils";
    nixpkgs.url = "nixpkgs/nixos-unstable";
  };

  outputs = { self, crane, flake-utils, nixpkgs, ... }@inputs:
    flake-utils.lib.eachDefaultSystem (system:
      let
        inherit (pkgs) lib;
        pkgs = import nixpkgs { inherit system; };
        fenix = inputs.fenix.packages.${system};
        craneLib = crane.lib.${system}.overrideToolchain toolchain.toolchain;
        mkSrc = extraPaths: with lib.fileset; let
          root = ./.;
          rustFiles = fromSource (craneLib.cleanCargoSource root);
          fileset = union rustFiles (unions extraPaths);
        in
        toSource { inherit root fileset; };

        ## Customize here ##
        toolchain = fenix.complete; # or fenix.stable;
        stdenv = pkgs.stdenvAdapters.useMoldLinker pkgs.stdenv;
      in
      {
        packages.default = craneLib.buildPackage {
          inherit stdenv;
          src = mkSrc [ ];
          strictDeps = true;
          buildInputs = [
            # Add additional build inputs here
          ] ++ lib.optionals pkgs.stdenv.isDarwin [
            # Additional darwin specific inputs can be set here
            pkgs.libiconv
          ];
          # Additional environment variables can be set directly
          # MY_CUSTOM_VAR = "some value";
        };

        devShells.default = pkgs.mkShell.override { inherit stdenv; }
          {
            nativeBuildInputs = with pkgs; [
              # Add additional build inputs here
            ] ++ (with toolchain; [
              cargo
              clippy
              rustfmt
              rustc
              fenix.rust-analyzer
            ]);
            RUST_SRC_PATH = "${toolchain.rust-src}/lib/rustlib/src/rust/library";
          };
      }
    );
}
