"2 versions of the same code" is not a very precise description. Either it's one chunk of code or two chunks, or one chunk that extends the other chunk in some way.
What we ended up in my case was one chunk of code (server) that extends a shared chunk (server/client), with plenty of server vs. client branching inside the shared chunk, either on a boolean flag or the presence of some data structure that only exists in one environment.
I have never seen the use case that many people flippantly claim is so easy, which is the "one chunk" concept, nor have I seen a chunk of server- or client-only code extend shared server-client code in a way I would describe as clean. Stuff tends to get messy when you have to deal with the space between the server and the client, like cookies, asset loading, or third-party services, or when you have to do fancy UX tricks. Then users who are used to "traditional" websites do things like refresh the page at weird times, click buttons more than once, load the app from the wrong URL, use the wrong browser, click things too fast, leave a tab open too long, and so on. And then, as others have mentioned, you have sensitive logic that needs to live only on the server for business reasons. Then the framework you're using moves too quickly or not quickly enough to support a browser feature you didn't know you needed until right now. All this stuff only comes in later, once the app meets the ground, and is rarely discussed in initial architecture meetings. The only way I could possibly see these solutions as cleaner than the old "two-chunk" way are if I were to automatically dismiss all those pragmatic concerns or consider them to be cleaner simply by virtue of the fact that they're different.
It's frustrating to me because I see so much optimism on online forums about "Universal" JS as this earth-shaking sea change on the verge of happening, even though honestly it's been 10 years since NodeJS came out and first made Universal possible. It makes me feel a bit like an old fogey for throwing up my hands and saying, "Let's just let it go and stick to the original design of the web," meaning, two chunks. But that's the only way possible for me to deliver the real requirements I have on projects without driving myself crazy.