It's frustrating that it forces you to jump into handling async code, though, in all cases. This wasn't always the case, and for good reason: sometimes async code is just vastly more complicated for no actual benefit if you can tolerate the FFI causing a crash at any calling point.
The interest in Elm took a major hit after the compiler banned use of JS.
That is what I mean! You need static top-level declarations of every out-of-elm iteration you want to do.
React on the other hand can wrap a JQuery calendar in a React component and from a programming point of view, using that component you would be none the wiser.
Also ports force everything to be async - and I am not talking just promises - I mean a new render per call response! So calculating 1+1 on a port requires generate a new render, and intercepting the result in a Redux-style handler, bubbling that into a component.
While you won't need to do 1+1 via ports, you might need to use a synchronous web-api feature that has not been ported to elm, or even use a math package to multiply some matrices.