Elm 0.19 - From a production perspective

Hi good people!

So, per that recent thing on reddit:

I wanted to post here.

  1. We love Elm!
  2. We really, really love Elm!
  3. We have (as of today) 22,844 lines of Elm code in production. (https://sgim.com) (still in soft-launch mode, but check it out…)

We seem to have two, maybe three, use cases that might not work under Elm 0.19, so I thought I’d post them here so the core elm team can comment or at least be aware of them.

  1. FIle upload. We need to allow a client to upload account statements, documents, pdfs, etc. to us. We implemented this using a native module.
  2. Form input formatting. For example, if someone types in a SSN, we turn 123456789 into 123-45-6789 as they type. Same with dates, dollar values, phone numbers, etc. We use cleave.js as well as a native module to do this. (We spent many hours trying to do this w/o resorting to native code, but ultimately had to go that route.)
  3. Phoenix sockets. This package is an effect manager. https://saschatimme.github.io/elm-phoenix/

That’s pretty much it.

Although the native code is only 140 lines of JS, it is critical, and we would not upgrade to Elm 0.19 without a way to accomplish the same end result.

With respect to the Phoenix sockets library, that’s how our front-end communicates with our server (running Phoenix/Elixir), so obviously we couldn’t upgrade unless that was working in Elm 0.19.

Rock on, and thank you for writing Elm in the first place!

Adam

ps having said all this, I love Elm so much I’d probably just stick with it anyway at 0.18! It’s that good. We have yet to encounter a true bug in 0.18, and have never had an issue we couldn’t work around either via ports or native code. Literally, the only complaint I have are compile times, which can be quite long if changing a module used by lots of other modules or if doing a full-compile.

pps happy to take this offline, or on slack or whatever.

17 Likes

Thanks for the writeup. Curious what trouble you ran into doing file uploads with ports.

2 Likes

Mod Note: This thread is a “Request Feedback” topic. That means @madasebrof has question, and we are going to try to help. There were a bunch of comments I would categorize as “related self-expression” that did not help with the topic goal, so I removed those. If you want to help out, great! If you have your own topic, start a new thread for it! I think the path of working through specifics could be really valuable, both to OP and to me (because I want folks to be able to upgrade!)

7 Likes

Hey, @madasebrof

As an outsider I can’t really tell you what’s best for your team, but I can at least offer you what I would do if my team was given the task of upgrading. I’ll try to call out the constraints that we have so that you can match them up against your own.

We’ve gotten some moderator assistance already and hopefully that works for us, but in case this post ends up becoming about sharing opinions on ports again, you can message me in the elm slack directly at @luke too and we’ll see if we can get you the help you’re looking for.

  1. File Upload

I’ve implemented production code for file uploads using ports and I’m quite satisfied with how it turned out. Port-specific things aside, I personally prefer the subscription style of managing upload states. The point is, this one is totally doable and the code you end up writing will be fine.

Evidence, for the skeptics:

  1. Form input formatting

I agree with the sentiment that it’s no fun to interoperate with synchronous code using ports. It feels frustrating, for sure. This circumstance of form inputs is interesting, though, because for me and my team, the first thing I would reach for is a Custom Element. I’d write an element that calls the formatting functions prior to either setting the value of the input, which is a child of your custom element, or prior to triggering a change event, whichever is the right place. Keep in mind though that really sufficient browser support and polyfills for this feature only get you as far back as IE11. Barring that, and since you’ve made it clear that you can’t rewrite the functions, I would just shrug my shoulders and use a port. We recently used a custom element to replace a native modules dealing with inputs in production at NoRedInk. I can’t link to it because it’s in a proprietary code base but I’ll be writing an speaking about it over the next couple months.

  1. Phoenix sockets

Some good news here is that, since this project is not a user of Native modules but just an effect manager, it can be implemented with relatively minimal modification without using an effect manager as well. So what I would do, and this is similar to things that we have done, is see about forking the repository and substituting the effect manager stuff for some state that lives in the model. Effect managers aren’t that conceptually different from regular Elm architecture stuff. This might end up being more work than just using ports to set stuff up in JS, but there’s also the chance the original author would take the PR and then this package could be published! If that’s no good, I would go for the ports. An outgoing port to ask JS code to subscribe and unsubscribe to stuff, and an incoming one to receive messages.

Let me know if I’ve made anything more confusing, and always feel free to reach out in slack, like I said.

13 Likes

Awesome, thanks for all the replies!

We will mos def be on the front-lines when 0.19 is released and will for sure try to get these things ported to 0.19 right away.

As I said, I just wanted to make these things known to folks like @evancz & @luke as 0.19 is being baked, so I’ve accomplished my goal.

Also, will try the custom element thing as well as the file-upload thing. I’d love to have zero JS. Also, I’m confident that, if it’s possible to do, we will be able to re-write the Phoenix sockets to not use an effect manager. I more just wanted to make sure that doors remain open for us to do that.

Personally, I am fine with the “constraints” of Elm. Our code never breaks. It’s amazing. It’s just that there needs to be a way to replicate all JS functionality. And I’m fine if sometimes it’s a bit more complicated to implement. To me, the trade-off is very worth it.

18 Likes

What is the situation with file upload?

I see that location of Elm files changed to https://github.com/ellie-app/ellie/tree/master/assets/src/ but I can’t find Aws.elm file.

1 Like

Hi folks,

I’m in a similar situation with upload (video logistics platform, 100+GB files) and input formatting (video timecode). We haven’t migrated yet, because we used a bunch of native modules, and entire vdom is constructed with (two) operators :yum: :face_with_hand_over_mouth: . Migrating will be the opportunity for us to improve perfs/ux using webworkers (md5 large files is messing with the main thread, and each window is responsible for its upload), but the basics is sending the drop event as elm Value to ports, then use Evaporate.js to manage the queue/retries/paralleled. For the rest of the Native, it’ll be either ports or custom elements.

1 Like