🕧 A clock UI component written in Elm.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Elm Timer

A simple digital clock that can either count to a future date or go backwards (countdown).

This project is no longer maintained

You can use it if you're still on Elm 0.16, however if you're using a more recent version of Elm there is an easier way of doing the same thing this library does. For example, for Elm 0.18 (code taken from the guide):

import Html exposing (Html)
import Svg exposing (..)
import Svg.Attributes exposing (..)
import Time exposing (Time, second)

main =
    { init = init
    , view = view
    , update = update
    , subscriptions = subscriptions


type alias Model = Time

init : (Model, Cmd Msg)
init =
  (0, Cmd.none)


type Msg
  = Tick Time

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    Tick newTime ->
      (newTime, Cmd.none)


subscriptions : Model -> Sub Msg
subscriptions model =
  Time.every second Tick


view : Model -> Html Msg
view model =
    angle =
      turns (Time.inMinutes model)

    handX =
      toString (50 + 40 * cos angle)

    handY =
      toString (50 + 40 * sin angle)
    svg [ viewBox "0 0 100 100", width "300px" ]
      [ circle [ cx "50", cy "50", r "45", fill "#0B79CE" ] []
      , line [ x1 "50", y1 "50", x2 handX, y2 handY, stroke "#023963" ] []

Below you'll find instructions to set up this library, in case you're still interested.

Getting started

No dependencies are required. Just grab the package and you're good to go.

elm package install simonewebdesign/elm-timer

A couple examples are provided: simple and countdown. The former doesn't use StartApp; the latter does.

You can either have a look at the examples or read below to get started.

Wire it up with StartApp

First of all, import the module:

import Timer

Then add it to your model:

type alias Model =
  { timer : Timer.Model }

Provide an initial value for it:

initialModel =
  { timer = Timer.init }

Define an action:

type Action
  = NoOp
  | TimerAction Timer.Action

Update your update:

update action model =
  case action of
    NoOp ->
      ( model, Effects.none )

    TimerAction subAction ->
      ( { model | timer = Timer.update subAction model.timer }
      , Effects.none


Add it to your view:

view address model =
  text (Timer.view model.timer)

And feed it to StartApp:

app =
    { init = ( initialModel, Effects.none )
    , update = update
    , view = view
    , inputs = [ Signal.map TimerAction Timer.tick ]

If everything's wired up correctly, you should be able to see a timer in your app.

A backwards clock (aka countdown)

If you want to reverse the clock, just use Timer.countdown instead of Timer.tick. For example if you're using StartApp your configuration will look like:

app =
    { inputs = [ Signal.map TimerAction Timer.countdown ]
    , ...


There are a couple of things that are being used internally, but I figured they might be useful.


The clock function is a Signal Int that receives a new value every second.


Another function that just adds a leading zero to a number only if it's just a single digit. The signature is addLeadingZero : number -> String.