Getting rid of ports modules

We don’t really need ports modules.

Communication to and from JS can be handled by an output : Value -> Cmd msg function and a new program type with a field like input : Decoder msg.

On the JS side, instead of app.ports.portName there can simply be app.subscribe and app.send.

Getting rid of ports modules would simplify the syntax and would get rid issues like this one.

What do you think about this idea?


I can’t judge for certain what the compiler could cope with, but some sort of specific indication that you are branching into js seems helpful in general.

What interests me in this area is when it will be possible to distribute code using ports via packages.elm-lang. Given the mantra of ‘use ports, use ports,…’ we need to make it possible to use them in a re-usable way

If we get rid of ports, we also get rid of the restriction on using ports with the :slight_smile: (there will no longer be ports modules that would prevent the package from being published)

Seems quite a bit simpler, and for me, this is pretty much how I’m already doing it. Didn’t Murphy do an Elm-conf talk advicing the same pattern?

Yes, it is very much aligned with what Murphy presented at elm-conf.

In the future Elm might target something other than JavaScript (like WebAssembly), and if all published Elm packages are written purely in Elm, this gets a lot easier. I also think it’s a good thing that all the packages I use are written purely in Elm, as that gives a lot of nice compile time guarantees. I can see your motivation, but I believe this issue will decrease as the number of published Elm packages increases.

What is “this issue” that you mention here?
I’m confused on how getting rid of ports modules is affected by the number of Elm packages.

The trouble is, I would download you package and find that it did not work because I need to also install its port driver. If the port driver were also downloaded automatically, it is the same thing as a free for all on native code, and then the Elm platform will grow in an uncontrolled way and the user experience may suffer.


The proposed idea here is not tied to the elm-ports-driver. It is simply a proposal that would simplify the language and eliminate a class of issues. It is also aligned with the way some people already do the ports code.

Sure, it would simplify the elm-ports-driver project too (on both sides) but that’s an added benefit.

I’m not arguing here for automatic downloads of JS code. A project like elm-ports-driver that could automate some of the things the currently are done with ports cannot be compared with Native because it is outside of the Elm code. You cannot use such a project to break the guarantees of Elm. Also, changes in the Kernel code do not affect in any way a project like this. Even moving the entire Kernel to something like WebAssembly would still not affect a project like this because it is entirely decoupled from Elm compiled code by the ports.


Ok, I did not necessarily mean your elm-ports-drive project; I would still have to install the .js code for the port myself, and that would mean that the package is broken out-of-the-box.

I don’t see that as broken out-of-the-box. Just because something requires you to have an extra step it does not mean that is broken out-of-the-box. elm-mdl behaves like this instructing its users to install the needed MDL css file in the output. I don’t think elm-mdl is broken out-of-the-box.

I also think that not allowing ports to be published encourages new solutions to be developed purely in Elm, versus just wrapping some .js library. If I am not mistaken, I think Richard said that in 0.19 there is only going to be 1 wrapped .js library left, and that will be evancz/elm-markdown. (Presumably because the documentation sites depend on it.)

I suppose our points of view are kind of academic anyway, as Even seems to have made his preferred direction of travel clear. I’m ok to sail with the good ship Elm.

Better if all the MDL css was done purely in Elm?

1 Like

I’m confused. Your comment makes it sound like I’m proposing something contrary to what Elm currently has.

As far as I see it, what I propose is equivalent of what we have now but with less special syntax and less issues.

1 Like

Sure thing but I still don’t see it as broken.

In which case I may be mis-understanding you.

Is your thinking along these lines: If there is just one input function and one output, there is no need to define any more ports than these. All we need is a Program type with input and output in it, and since these never change they might as well be allowed to be published.

Most likely instances of this Program type would not be published to the packages site anyway, as we do not have a way to compose Programs?

I think that’s exactly where this should go. Make input and output ports as a part of Html.Program types, and then it’s a part of the application, and not libraries that would be published. It makes total sense since ports are an application (and not a library) concern.

1 Like

Yes, I’m arguing for providing a way to define Programs that have these facilities included. As I said, the special ports syntax can be dropped by replacing it with a output: Value -> Cmd function and a special program that can take a decoder. Alternatively, the input can be input : (Value -> msg) -> Sub msg but I would prefer the decoder variant because the subscription variant enforces the use of a NoOp msg.

Allowing ports on is a recipe for troubles similar to the one described in this issue.

I don’t see how getting rid of ports would create problems that are impossible with the current policy. I would however be interested in learning about such problems.

I do not see why someone would want to publish an instance of a program like this. It would be useless from inside Elm. In any case, I think 0.19 will make a difference between application and package and I’m perfectly fine with banning Program altho I don’t see the point.

1 Like

I actually feel like elm-mdl is broken out of the box. I would have liked to know before hand - I like having ports for being pragmatic in production code - however I really don’t want other people’s javascript as a dependency - that’s why would use elm - it is not JavaScript.

My experience with JavaScript is quite limited. I actually want other people’s JavaScript when this cannot be avoided. I would prefer to code in Elm but if Elm cannot do something and I need to use the ports, I would prefer to have on the other side something that a person with much more JavaScript experience than me wrote.