After a bit of research on file uploads, I pared it down to the simplest method I could find. Here is the recipe I came up with.
The FileUtils module essentially wraps the JS File object in Http.Body as well as exposing common file info (name, size, contentType). Using Http.Body makes it quite easy to send files with normal Http calls. Unfortunately this does use native/kernel code, but this made it far easier to work with in Elm than if I used ports. I did actually try using decoders first to pull in the "e.target.files" property as a Value, but Elm just fails to decode it.
I also thought something like this could be a path forward to introduce basic file uploads into Elm's core. It is not a general solution for all binary formats. But it is a straightforward way to handle File objects from JS.