Elm was better without custom kernel modules and sync JS-interop.
It kept the Elm kernel small and portable. It forced the 3rd party package eco system to innovate and create things rather than just wrap existing Javscript libraries.
It has enable me to port the small kernel now to C++ for an Elm to native compiler.
Also, if you really wanted to bypass it and have your own kernel, that was always possible and not hard to do. Even in 0.18 custom effects modules could not be shared on the official package site.