The problem is that there's no obvious, simple way to bring the results of this query, structured and typed appropriately (with posts nested inside users), into our running code.
So we have to choose what we think is the least-worst compromise.
Since I wrote the library I am obviously anything but impartial, but the compromise I outlined above is one I'm pretty happy with (and it's much easier to read if you add a few line breaks). It's a bit noisier than your JOIN query, but for the price of that noise you get type safety and an appropriate JSON structure for the result.