Elm Language Ports (JS interop) Get started


Example

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Trying out ports</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="elm.js"></script>
    <script>
    
      var node = document.getElementById('app');
      var app = Elm.Main.embed(node);
      
      // subscribe to messages from Elm
      app.ports.toJs.subscribe(function(messageFromElm) {
        alert(messageFromElm);
        // we could send something back by
        // app.ports.fromJs.send('Hey, got your message! Sincerely, JS');
      });
      
      // wait three seconds and then send a message from JS to Elm
      setTimeout(function () {
        app.ports.fromJs.send('Hello from JS');
      }, 3000);
      
    </script>
  </body>
</html>

Main.elm

port module Main exposing (..)

import Html

port toJs : String -> Cmd msg
port fromJs : (String -> msg) -> Sub msg

main =
   Html.program
        { init = (Nothing, Cmd.none) -- our model will be the latest message from JS (or Nothing for 'no message yet')
        , update = update
        , view = view
        , subscriptions = subscriptions
        }

type Msg
    = GotMessageFromJs String

update msg model =
    case msg of
        GotMessageFromJs message ->
            (Just message, toJs "Hello from Elm")

view model =
    case model of
        Nothing ->
            Html.text "No message from JS yet :("
        Just message ->
            Html.text ("Last message from JS: " ++ message)

subscriptions model =
    fromJs GotMessageFromJs

Install the elm-lang/html package if you haven't yet by elm-package install elm-lang/html --yes.

Compile this code using elm-make Main.elm --yes --output elm.js so that the HTML file finds it.

If everything goes well, you should be able to open the index.html file with the "No message" text displayed. After three seconds the JS sends a message, Elm gets it, changes its model, sends a response, JS gets it and opens an alert.