Essentially, it boils down to how to get two very different module systems to work together. CommonJS (CJS) Modules are dynamic and synchronously loaded, ES Modules are static, immutable and asynchronously loaded. But no one wants to break the Node ecosystem, meaning that we want to be able to load CJS modules from ES modules and vice versa, ideally without the user having to know which kind of modules a package uses. (Currently you can't load ES modules from CJS modules, that will require a new asynchronous loading function.) Some people also want to be able to publish packages with exports in both kind of module.
Browsers didn't have any kind of modules previously, so they didn't have to make ES modules cooperate with anything. They could just do a simple implementation.
Any module system across such different environments as browsers and Node is going to have some tricky edge cases. Even though with the
--experimental-modules flag Node's ES Modules implementation is largely the same as a browser's, there are still differences. For example, browsers will only load from full URLs, but Node will load packages from
node_modules with only a package name.