I'm sorry that you've gotten bitten because it's frustrating when it happens, but "if a package requires a peer dependency,it's probably not worth using" is some cargo-cult stuff. Anything that acts as a extension system (coded to an interface) should use the project it's extending as a peerDependency. They are not "global variables", they're interfaces. It's what you're writing against! If you end up in dependency hell because of them, that means your dependencies are not speaking to the same interface, and that means you need to resolve the problem. Which can suck, I guess, having to actually do some work as a programmer, but somehow I think we'll all muddle through. Because the alternative is to silently have different APIs that will later break because the extended system has changed, and that is rather worse than actually knowing what's going on in your system.
React is a system that exists to be extended. Peer dependencies exist to facilitate this. Understanding one's tools makes cargo-cult sweeping-statement fears about milquetoast stuff really just unnecessary.
Flatpak is whatever (it's fancy /opt, that's fine) but, "jumping outside the web world", I'll put on my platform-architecture-is-my-actual-real-job hat right now and point out that Docker, while certainly appropriate for some use cases, is, for example, happy to cost you money in production when your big ol' app (shouts to my 4GB-heap-before-taking-a-request Ruby clients) can't copy-on-write. (After all, each process is supposed to be isolated, right? I mean, that's what people think...) There are real drawbacks to this approach, it's orthogonal to actually writing code, and the analogy doesn't really hold besides.