It's necessary to hardcode paths in order to ensure that the exact version of a dependency is linked into the executable.
Without this mechanism, nix packages would not be reproducible and self-contained.
Also, the path isn't really hardcoded. You can use a custom path, but that means you can't use binary caches.