Automatically derive Elm functions to query servant webservices.

Version on this page:0.7.1
LTS Haskell 22.30:0.7.3
Stackage Nightly 2023-12-26:0.7.3
Latest on Hackage:0.7.3

See all snapshots servant-elm appears in

BSD-3-Clause licensed by Matt Bray
Maintained by [email protected]
This version can be pinned in stack with:servant-elm-0.7.1@sha256:c354d82a2bbf69a7c66020a1a278055650aea678669e9a6db88ba24bf163e4c4,4577

Module documentation for 0.7.1

Servant Elm

Build Status

Generate Elm functions to query your Servant API!

Elm type generation coutesy of elm-bridge.


Servant Elm is available on Hackage.


First, some language pragmas and imports.

{-# LANGUAGE DataKinds         #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE TypeOperators     #-}

import           Elm.Derive   (defaultOptions, deriveBoth)

import           Servant.API  ((:>), Capture, Get, JSON)
import           Servant.Elm  (DefineElm (DefineElm), Proxy (Proxy), defElmImports, defElmOptions,

We have some Haskell-defined types and our Servant API.

data Book = Book
    { name :: String

deriveBoth defaultOptions ''Book

type BooksApi = "books" :> Capture "bookId" Int :> Get '[JSON] Book

Now we can generate Elm functions to query the API:

main :: IO ()
main =
    [ "Generated"
    , "MyApi"
    [ DefineElm (Proxy :: Proxy Book)
    (Proxy :: Proxy BooksApi)

Let’s save this as example.hs and run it:

$ stack runghc example.hs
Writing: my-elm-dir/Generated/MyApi.elm

Here’s what was generated:

module Generated.MyApi exposing(..)

import Json.Decode
import Json.Encode exposing (Value)
-- The following module comes from bartavelle/json-helpers
import Json.Helpers exposing (..)
import Dict exposing (Dict)
import Set
import Http
import String
import Url.Builder

type alias Book  =
   { name: String

jsonDecBook : Json.Decode.Decoder ( Book )
jsonDecBook =
   Json.Decode.succeed (\pname -> {name = pname})
   |> required "name" (Json.Decode.string)

jsonEncBook : Book -> Value
jsonEncBook  val =
   [ ("name", Json.Encode.string

getBooksByBookId : Int -> Http.Request Book
getBooksByBookId capture_bookId =
        params =
            List.filterMap identity
            { method =
            , headers =
            , url =
                    [ "books"
                    , capture_bookId |> String.fromInt
            , body =
            , expect =
                Http.expectJson <| jsonDecBook
            , timeout =
            , withCredentials =

See examples for a complete usage example, or take a look at mattjbray/servant-elm-example-app (elm 0.18) or haskell-servant/example-servant-elm (elm 0.19) for an example project using this library.


$ git clone
$ cd servant-elm
$ stack test
$ stack test --flag servant-elm:integration

To build all examples:

$ make examples

To run an example:

$ cd examples/e2e-tests
$ elm-reactor
# Open http://localhost:8000/elm/Main.elm



  • PR #61. Improving support for polymorphic data types


  • PR #59. Using the appropriate toString functions for different types


  • PR #57. mkUrl: Use urlBase for Dynamic case

  • Ticket #53. Don’t add a “query_” prefix to query params

  • Bug: Replace special symbols in query string param name

  • PR #49. Support Elm 0.19, migrate to elm-bridge, support http 2.0.0

  • Fix generation for APIs with response headers.
  • Support Servant’s Optional and Required modifiers for Headers and QueryParams (Header arguments are now Maybes by default). (phaazon) (#31)
  • Filter out forbidden Cookie header. (xilnocas) (#37)

  • Remove hyphens from generated function names. (servant-foreign-0.10 no longer does this for us.)

  • Allow passing the base URL dynamically in Elm. (#20)
  • Don’t use toString on Text parameters. (domenkozar) (#23, #24)
  • Fix query parameter generation. (domenkozar) (#25)

  • Prefix generated function arguments to ensure valid Elm identifiers (#21)
  • Put integration tests behind a Cabal flag. (#22)

  • Update for Elm 0.18 and the new elm-lang/http library.
  • Generated Elm functions now return an Http.Request value.

  • Use Text throughout the API.
  • We no longer auto-generate Elm sources for the types, encoders and decoders used in your API - you must now use elm-export’s toElmTypeSource functions explicitly. See the tests and examples for usage.
  • Allow setting options to pass to elm-export.
  • Update to servant-0.8 (purcell).
  • Basic support for custom headers.
  • Fix: String query params were being wrapped in double-quotes.
  • Test: verify that the generated code can be compiled by Elm (soenkehahn)

  • Fix for API endpoints that return Unit (kantp)

  • Convenience re-exports from Elm and Data.Proxy.
  • Add Haddoc documentation.


  • Initial release.