Ah! You asked about flakes as well. Just saw that. Basically flakes are a construct in Nix that enable you to (a) ensure that your Nix code is always "pinned" to specific revisions of your inputs (for example Nixpkgs but other inputs as well) and (b) to provide a simple and well understood system for sharing Nix code. So this command, for example, enables me to build Tailscale:
nix build github:tailscale/tailscale
I point Nix at an "address" and it knows which set of Nix build instructions to use. Basically that Tailscale repo has a flake.nix in the root that Nix looks at, specifically at the flake outputs. From there, it sees that there is an attribute called "packages" and then it sees that there's a package for the current system called "default," and then it builds that. So Nix expressions have universal "addresses" (they also did before flakes but flakes provide a standard structure for outputs and built-in pinning via flake.lock files).