Server-side Elm

elm server <file.elm> [--port N] [--static DIR] runs an Elm file as an HTTP server on the JIT interpreter. There are two shapes of server:

Both use the bundled Server module.

Requests and responses

type alias Request =
    { method : String, path : String, query : List ( String, String ), body : String }

type alias Response =
    { status : Int, contentType : String, body : String }

Response builders cover the common content types, and two request helpers parse the path and query:

HelperTypePurpose
textString -> Responsetext/plain body.
htmlString -> Responsetext/html body.
jsonString -> Responseapplication/json body.
cssString -> Responsetext/css body.
javascriptString -> Responseapplication/javascript body.
notFoundResponseA 404.
segmentsRequest -> List StringPath split on /, empties dropped.
paramString -> Request -> Maybe StringLook up a query parameter.

A stateless server

The bundled SimpleServerShowcase.elm routes on the path segments and echoes query parameters:

module Main exposing (handle)

import Server exposing (..)

handle : Request -> Response
handle req =
    case segments req of
        [] ->
            html "<h1>Hello from Elm</h1>"

        [ "ping" ] ->
            text "pong"

        [ "greet" ] ->
            text ("Hello, " ++ Maybe.withDefault "world" (param "name" req) ++ "!")

        _ ->
            notFound
elm server SimpleServerShowcase --port 8080
curl localhost:8080/ping              # -> pong
curl 'localhost:8080/greet?name=Ada'  # -> Hello, Ada!

SimpleServerShowcase resolves to the bundled demo; you can also pass a path to your own file.

A stateful server

A stateful program holds a model in memory, updates it on every request, and advances it on a timer — so the page changes over time without any client action:

type alias Program model =
    { init : model
    , onRequest : Request -> model -> ( model, Response )
    , onTick : model -> model
    , tickMillis : Int
    }

Model access is serialized, so onRequest and onTick never interleave. The bundled LiveDashboard.elm is a complete example: an in-memory time series advanced by a seeded random walk on every tick, with the server itself serving

elm server LiveDashboard --port 8080
# open http://localhost:8080 — the chart updates on its own as the server ticks

Serving static files

Pass --static DIR to serve text assets (HTML/CSS/JS/JSON/SVG) from a directory *before* the handler runs; path traversal outside the directory is refused. This lets a single command serve a built front-end plus a dynamic API from the same Elm app.