diff --git a/containers/elm/.devcontainer/Dockerfile b/containers/elm/.devcontainer/Dockerfile
new file mode 100644
index 0000000000..655901a789
--- /dev/null
+++ b/containers/elm/.devcontainer/Dockerfile
@@ -0,0 +1,32 @@
+#-------------------------------------------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
+#-------------------------------------------------------------------------------------------------------------
+
+FROM debian:9
+
+# Avoid warnings by switching to noninteractive
+ENV DEBIAN_FRONTEND=noninteractive
+
+# Configuring Elm version
+ARG ELM_VERSION=0.19.0
+
+
+# Configure apt and install packages
+RUN apt-get update \
+ && apt-get -y install --no-install-recommends apt-utils 2>&1 \
+ #
+ # Verify git and needed tools are installed
+ && apt-get install -y git procps \
+ && apt-get install -y wget \
+ #
+ # Install elm globally
+ && wget -O - https://github.com/elm/compiler/releases/download/${ELM_VERSION}/binary-for-linux-64-bit.gz | gunzip -c > /usr/local/bin/elm && chmod +x /usr/local/bin/elm \
+ #
+ # Clean up
+ && apt-get autoremove -y \
+ && apt-get clean -y \
+ && rm -rf /var/lib/apt/lists/*
+
+# Switch back to dialog for any ad-hoc use of apt-get
+ENV DEBIAN_FRONTEND=dialog
diff --git a/containers/elm/.devcontainer/devcontainer.json b/containers/elm/.devcontainer/devcontainer.json
new file mode 100644
index 0000000000..03e781e425
--- /dev/null
+++ b/containers/elm/.devcontainer/devcontainer.json
@@ -0,0 +1,18 @@
+{
+ "name": "Elm",
+ "dockerFile": "Dockerfile",
+
+ // Uncomment the next line if you want to publish any ports.
+ // 8000 is the default port used for the `elm reactor` command
+ //"appPort": [8000],
+
+ // Uncomment the next line if you want to add in default container specific settings.json values
+ // "settings": { "workbench.colorTheme": "Quiet Light" },
+
+ // Uncomment the next line to run commands after the container is created.
+ // "postCreateCommand": "elm make",
+
+ "extensions": [
+ "sbrink.elm"
+ ]
+}
diff --git a/containers/elm/.npmignore b/containers/elm/.npmignore
new file mode 100644
index 0000000000..1d72d293eb
--- /dev/null
+++ b/containers/elm/.npmignore
@@ -0,0 +1,4 @@
+README.md
+test-project
+.vscode
+.npmignore
diff --git a/containers/elm/README.md b/containers/elm/README.md
new file mode 100644
index 0000000000..0ed264bd81
--- /dev/null
+++ b/containers/elm/README.md
@@ -0,0 +1,51 @@
+# Elm
+
+## Summary
+
+*Develop Elm based applications. Includes the elm extension & binary
+
+| Metadata | Value |
+|----------|-------|
+| *Contributors* | xWiiLLz |
+| *Definition type* | Dockerfile |
+| *Languages, platforms* | Elm |
+
+## Using this definition with an existing folder
+
+This definition does not require any special steps to use. Just follow these steps:
+
+1. If this is your first time using a development container, please follow the [getting started steps](https://aka.ms/vscode-remote/containers/getting-started) to set up your machine.
+
+2. To use VS Code's copy of this definition:
+ 1. Start VS Code and open your project folder.
+ 2. Press F1 select and **Remote-Containers: Add Development Container Configuration Files...** from the command palette.
+ 3. Select the **Elm** definition.
+
+3. To use latest-and-greatest copy of this definition from the repository:
+ 1. Clone this repository.
+ 2. Copy the contents of `containers/elm/.devcontainer` to the root of your project folder.
+ 3. Start VS Code and open your project folder.
+
+4. After following step 2 or 3, the contents of the `.devcontainer` folder in your project can be adapted to meet your needs.
+
+5. Finally, press F1 and run **Remote-Containers: Reopen Folder in Container** to start using the definition.
+
+## Testing the definition
+
+This definition includes some test code that will help you verify it is working as expected on your system. Follow these steps:
+
+1. If this is your first time using a development container, please follow the [getting started steps](https://aka.ms/vscode-remote/containers/getting-started) to set up your machine.
+2. Clone this repository.
+3. Start VS Code, press F1, and select **Remote-Containers: Open Folder in Container...**
+4. Select the `containers/elm` folder.
+5. After the folder has opened in the container, open a terminal in the `test-project` folder (`cd test-project/`) and run the following command: `elm reactor`
+6. Once the project is running, press F1 and select **Remote-Containers: Forward Port from Container...**
+7. Select port 8000 and click the "Open Browser" button in the notification that appears.
+8. You should see the Elm startup page.
+9. From here, you can browse any of the files in the `examples` folder to see them compiled and ran in your browser 😊
+
+## License
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+Licensed under the MIT License. See [LICENSE](https://github.com/Microsoft/vscode-dev-containers/blob/master/LICENSE).
\ No newline at end of file
diff --git a/containers/elm/test-project/.gitignore b/containers/elm/test-project/.gitignore
new file mode 100644
index 0000000000..d86ae43c0e
--- /dev/null
+++ b/containers/elm/test-project/.gitignore
@@ -0,0 +1,2 @@
+elm-stuff
+elm.js
\ No newline at end of file
diff --git a/containers/elm/test-project/LICENSE b/containers/elm/test-project/LICENSE
new file mode 100644
index 0000000000..2377b9c65f
--- /dev/null
+++ b/containers/elm/test-project/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2014-2016, Evan Czaplicki
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of the {organization} nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/containers/elm/test-project/README.md b/containers/elm/test-project/README.md
new file mode 100644
index 0000000000..53ea50e4e4
--- /dev/null
+++ b/containers/elm/test-project/README.md
@@ -0,0 +1,28 @@
+# Elm
+
+[Elm](https://elm-lang.org/) is a programming language that compiles to JavaScript. It is known for its friendly error messages, helping you find issues quickly and refactor large projects with confidence. Elm is also [very fast](https://elm-lang.org/blog/blazing-fast-html-round-two) and [very small](https://elm-lang.org/blog/small-assets-without-the-headache) when compared with React, Angular, Ember, etc.
+
+This repo focuses on **The Elm Architecture**, an architecture pattern you see in all Elm programs. It has influenced projects like Redux that borrow core concepts but add many JS-focused ideas.
+
+
+## The Elm Architecture
+
+The Elm Architecture is a simple pattern for architecting webapps. The core idea is that your code is built around a `Model` of your application state, a way to `update` your model, and a way to `view` your model.
+
+To learn more about this, read the [the official guide][guide] and check out [this section][arch] which is all about The Elm Architecture. This repo is a collection of all the examples in that section, so you can follow along and compile things on your computer as you read through.
+
+[guide]: https://guide.elm-lang.org/
+[arch]: https://guide.elm-lang.org/architecture/
+
+
+## Run The Examples
+
+After you [install](https://guide.elm-lang.org/install.html), run the following commands in your terminal to download this repo and start a server that compiles Elm for you:
+
+```bash
+git clone https://github.com/evancz/elm-architecture-tutorial.git
+cd elm-architecture-tutorial
+elm reactor
+```
+
+Now go to [http://localhost:8000/](http://localhost:8000/) and start looking at the `examples/` directory. When you edit an Elm file, just refresh the corresponding page in your browser and it will recompile!
diff --git a/containers/elm/test-project/elm.json b/containers/elm/test-project/elm.json
new file mode 100644
index 0000000000..11db8563b1
--- /dev/null
+++ b/containers/elm/test-project/elm.json
@@ -0,0 +1,28 @@
+{
+ "type": "application",
+ "source-directories": [
+ "examples"
+ ],
+ "elm-version": "0.19.0",
+ "dependencies": {
+ "direct": {
+ "elm/browser": "1.0.0",
+ "elm/core": "1.0.2",
+ "elm/html": "1.0.0",
+ "elm/http": "2.0.0",
+ "elm/json": "1.1.1",
+ "elm/random": "1.0.0",
+ "elm/time": "1.0.0",
+ "elm/url": "1.0.0"
+ },
+ "indirect": {
+ "elm/bytes": "1.0.3",
+ "elm/file": "1.0.1",
+ "elm/virtual-dom": "1.0.0"
+ }
+ },
+ "test-dependencies": {
+ "direct": {},
+ "indirect": {}
+ }
+}
\ No newline at end of file
diff --git a/containers/elm/test-project/examples/01-button.elm b/containers/elm/test-project/examples/01-button.elm
new file mode 100644
index 0000000000..2599444620
--- /dev/null
+++ b/containers/elm/test-project/examples/01-button.elm
@@ -0,0 +1,41 @@
+import Browser
+import Html exposing (Html, button, div, text)
+import Html.Events exposing (onClick)
+
+
+main =
+ Browser.sandbox { init = init, update = update, view = view }
+
+
+-- MODEL
+
+type alias Model = Int
+
+init : Model
+init =
+ 0
+
+
+-- UPDATE
+
+type Msg = Increment | Decrement
+
+update : Msg -> Model -> Model
+update msg model =
+ case msg of
+ Increment ->
+ model + 1
+
+ Decrement ->
+ model - 1
+
+
+-- VIEW
+
+view : Model -> Html Msg
+view model =
+ div []
+ [ button [ onClick Decrement ] [ text "-" ]
+ , div [] [ text (String.fromInt model) ]
+ , button [ onClick Increment ] [ text "+" ]
+ ]
\ No newline at end of file
diff --git a/containers/elm/test-project/examples/02-field.elm b/containers/elm/test-project/examples/02-field.elm
new file mode 100644
index 0000000000..3041f29fbc
--- /dev/null
+++ b/containers/elm/test-project/examples/02-field.elm
@@ -0,0 +1,53 @@
+import Browser
+import Html exposing (Html, Attribute, div, input, text)
+import Html.Attributes exposing (..)
+import Html.Events exposing (onInput)
+
+
+
+-- MAIN
+
+
+main =
+ Browser.sandbox { init = init, update = update, view = view }
+
+
+
+-- MODEL
+
+
+type alias Model =
+ { content : String
+ }
+
+
+init : Model
+init =
+ { content = "" }
+
+
+
+-- UPDATE
+
+
+type Msg
+ = Change String
+
+
+update : Msg -> Model -> Model
+update msg model =
+ case msg of
+ Change newContent ->
+ { model | content = newContent }
+
+
+
+-- VIEW
+
+
+view : Model -> Html Msg
+view model =
+ div []
+ [ input [ placeholder "Text to reverse", value model.content, onInput Change ] []
+ , div [] [ text (String.reverse model.content) ]
+ ]
diff --git a/containers/elm/test-project/examples/03-form.elm b/containers/elm/test-project/examples/03-form.elm
new file mode 100644
index 0000000000..3126715620
--- /dev/null
+++ b/containers/elm/test-project/examples/03-form.elm
@@ -0,0 +1,78 @@
+import Browser
+import Html exposing (..)
+import Html.Attributes exposing (..)
+import Html.Events exposing (onInput)
+
+
+
+-- MAIN
+
+
+main =
+ Browser.sandbox { init = init, update = update, view = view }
+
+
+
+-- MODEL
+
+
+type alias Model =
+ { name : String
+ , password : String
+ , passwordAgain : String
+ }
+
+
+init : Model
+init =
+ Model "" "" ""
+
+
+
+-- UPDATE
+
+
+type Msg
+ = Name String
+ | Password String
+ | PasswordAgain String
+
+
+update : Msg -> Model -> Model
+update msg model =
+ case msg of
+ Name name ->
+ { model | name = name }
+
+ Password password ->
+ { model | password = password }
+
+ PasswordAgain password ->
+ { model | passwordAgain = password }
+
+
+
+-- VIEW
+
+
+view : Model -> Html Msg
+view model =
+ div []
+ [ viewInput "text" "Name" model.name Name
+ , viewInput "password" "Password" model.password Password
+ , viewInput "password" "Re-enter Password" model.passwordAgain PasswordAgain
+ , viewValidation model
+ ]
+
+
+viewInput : String -> String -> String -> (String -> msg) -> Html msg
+viewInput t p v toMsg =
+ input [ type_ t, placeholder p, value v, onInput toMsg ] []
+
+
+viewValidation : Model -> Html msg
+viewValidation model =
+ if model.password == model.passwordAgain then
+ div [ style "color" "green" ] [ text "OK" ]
+ else
+ div [ style "color" "red" ] [ text "Passwords do not match!" ]
diff --git a/containers/elm/test-project/examples/04-maybe.elm b/containers/elm/test-project/examples/04-maybe.elm
new file mode 100644
index 0000000000..fd41c74d75
--- /dev/null
+++ b/containers/elm/test-project/examples/04-maybe.elm
@@ -0,0 +1,65 @@
+import Browser
+import Html exposing (Html, Attribute, span, input, text)
+import Html.Attributes exposing (..)
+import Html.Events exposing (onInput)
+
+
+
+-- MAIN
+
+
+main =
+ Browser.sandbox { init = init, update = update, view = view }
+
+
+
+-- MODEL
+
+
+type alias Model =
+ { input : String
+ }
+
+
+init : Model
+init =
+ { input = "" }
+
+
+
+-- UPDATE
+
+
+type Msg
+ = Change String
+
+
+update : Msg -> Model -> Model
+update msg model =
+ case msg of
+ Change newInput ->
+ { model | input = newInput }
+
+
+
+-- VIEW
+
+
+view : Model -> Html Msg
+view model =
+ case String.toFloat model.input of
+ Just celsius ->
+ viewConverter model.input "blue" (String.fromFloat (celsius * 1.8 + 32))
+
+ Nothing ->
+ viewConverter model.input "red" "???"
+
+
+viewConverter : String -> String -> String -> Html Msg
+viewConverter userInput color equivalentTemp =
+ span []
+ [ input [ value userInput, onInput Change, style "width" "40px" ] []
+ , text "°C = "
+ , span [ style "color" color ] [ text equivalentTemp ]
+ , text "°F"
+ ]
diff --git a/containers/elm/test-project/examples/05-http.elm b/containers/elm/test-project/examples/05-http.elm
new file mode 100644
index 0000000000..1483834eba
--- /dev/null
+++ b/containers/elm/test-project/examples/05-http.elm
@@ -0,0 +1,82 @@
+import Browser
+import Html exposing (Html, text, pre)
+import Http
+
+
+
+-- MAIN
+
+
+main =
+ Browser.element
+ { init = init
+ , update = update
+ , subscriptions = subscriptions
+ , view = view
+ }
+
+
+
+-- MODEL
+
+
+type Model
+ = Failure
+ | Loading
+ | Success String
+
+
+init : () -> (Model, Cmd Msg)
+init _ =
+ ( Loading
+ , Http.get
+ { url = "https://elm-lang.org/assets/public-opinion.txt"
+ , expect = Http.expectString GotText
+ }
+ )
+
+
+
+-- UPDATE
+
+
+type Msg
+ = GotText (Result Http.Error String)
+
+
+update : Msg -> Model -> (Model, Cmd Msg)
+update msg model =
+ case msg of
+ GotText result ->
+ case result of
+ Ok fullText ->
+ (Success fullText, Cmd.none)
+
+ Err _ ->
+ (Failure, Cmd.none)
+
+
+
+-- SUBSCRIPTIONS
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+ Sub.none
+
+
+
+-- VIEW
+
+
+view : Model -> Html Msg
+view model =
+ case model of
+ Failure ->
+ text "I was unable to load your book."
+
+ Loading ->
+ text "Loading..."
+
+ Success fullText ->
+ pre [] [ text fullText ]
diff --git a/containers/elm/test-project/examples/06-json.elm b/containers/elm/test-project/examples/06-json.elm
new file mode 100644
index 0000000000..d4824865b8
--- /dev/null
+++ b/containers/elm/test-project/examples/06-json.elm
@@ -0,0 +1,115 @@
+import Browser
+import Html exposing (..)
+import Html.Attributes exposing (..)
+import Html.Events exposing (..)
+import Http
+import Json.Decode exposing (Decoder, field, string)
+
+
+
+-- MAIN
+
+
+main =
+ Browser.element
+ { init = init
+ , update = update
+ , subscriptions = subscriptions
+ , view = view
+ }
+
+
+
+-- MODEL
+
+
+type Model
+ = Failure
+ | Loading
+ | Success String
+
+
+init : () -> (Model, Cmd Msg)
+init _ =
+ (Loading, getRandomCatGif)
+
+
+
+-- UPDATE
+
+
+type Msg
+ = MorePlease
+ | GotGif (Result Http.Error String)
+
+
+update : Msg -> Model -> (Model, Cmd Msg)
+update msg model =
+ case msg of
+ MorePlease ->
+ (Loading, getRandomCatGif)
+
+ GotGif result ->
+ case result of
+ Ok url ->
+ (Success url, Cmd.none)
+
+ Err _ ->
+ (Failure, Cmd.none)
+
+
+
+-- SUBSCRIPTIONS
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+ Sub.none
+
+
+
+-- VIEW
+
+
+view : Model -> Html Msg
+view model =
+ div []
+ [ h2 [] [ text "Random Cats" ]
+ , viewGif model
+ ]
+
+
+viewGif : Model -> Html Msg
+viewGif model =
+ case model of
+ Failure ->
+ div []
+ [ text "I could not load a random cat for some reason. "
+ , button [ onClick MorePlease ] [ text "Try Again!" ]
+ ]
+
+ Loading ->
+ text "Loading..."
+
+ Success url ->
+ div []
+ [ button [ onClick MorePlease, style "display" "block" ] [ text "More Please!" ]
+ , img [ src url ] []
+ ]
+
+
+
+-- HTTP
+
+
+getRandomCatGif : Cmd Msg
+getRandomCatGif =
+ Http.get
+ { url = "https://api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=cat"
+ , expect = Http.expectJson GotGif gifDecoder
+ }
+
+
+gifDecoder : Decoder String
+gifDecoder =
+ field "data" (field "image_url" string)
diff --git a/containers/elm/test-project/examples/07-random.elm b/containers/elm/test-project/examples/07-random.elm
new file mode 100644
index 0000000000..b11f637685
--- /dev/null
+++ b/containers/elm/test-project/examples/07-random.elm
@@ -0,0 +1,77 @@
+import Browser
+import Html exposing (..)
+import Html.Events exposing (..)
+import Random
+
+
+
+-- MAIN
+
+
+main =
+ Browser.element
+ { init = init
+ , update = update
+ , subscriptions = subscriptions
+ , view = view
+ }
+
+
+
+-- MODEL
+
+
+type alias Model =
+ { dieFace : Int
+ }
+
+
+init : () -> (Model, Cmd Msg)
+init _ =
+ ( Model 1
+ , Cmd.none
+ )
+
+
+
+-- UPDATE
+
+
+type Msg
+ = Roll
+ | NewFace Int
+
+
+update : Msg -> Model -> (Model, Cmd Msg)
+update msg model =
+ case msg of
+ Roll ->
+ ( model
+ , Random.generate NewFace (Random.int 1 6)
+ )
+
+ NewFace newFace ->
+ ( Model newFace
+ , Cmd.none
+ )
+
+
+
+-- SUBSCRIPTIONS
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+ Sub.none
+
+
+
+-- VIEW
+
+
+view : Model -> Html Msg
+view model =
+ div []
+ [ h1 [] [ text (String.fromInt model.dieFace) ]
+ , button [ onClick Roll ] [ text "Roll" ]
+ ]
\ No newline at end of file
diff --git a/containers/elm/test-project/examples/08-time.elm b/containers/elm/test-project/examples/08-time.elm
new file mode 100644
index 0000000000..9f6ed6bad5
--- /dev/null
+++ b/containers/elm/test-project/examples/08-time.elm
@@ -0,0 +1,81 @@
+import Browser
+import Html exposing (..)
+import Task
+import Time
+
+
+
+-- MAIN
+
+
+main =
+ Browser.element
+ { init = init
+ , view = view
+ , update = update
+ , subscriptions = subscriptions
+ }
+
+
+
+-- MODEL
+
+
+type alias Model =
+ { zone : Time.Zone
+ , time : Time.Posix
+ }
+
+
+init : () -> (Model, Cmd Msg)
+init _ =
+ ( Model Time.utc (Time.millisToPosix 0)
+ , Task.perform AdjustTimeZone Time.here
+ )
+
+
+
+-- UPDATE
+
+
+type Msg
+ = Tick Time.Posix
+ | AdjustTimeZone Time.Zone
+
+
+
+update : Msg -> Model -> (Model, Cmd Msg)
+update msg model =
+ case msg of
+ Tick newTime ->
+ ( { model | time = newTime }
+ , Cmd.none
+ )
+
+ AdjustTimeZone newZone ->
+ ( { model | zone = newZone }
+ , Cmd.none
+ )
+
+
+
+-- SUBSCRIPTIONS
+
+
+subscriptions : Model -> Sub Msg
+subscriptions model =
+ Time.every 1000 Tick
+
+
+
+-- VIEW
+
+
+view : Model -> Html Msg
+view model =
+ let
+ hour = String.fromInt (Time.toHour model.zone model.time)
+ minute = String.fromInt (Time.toMinute model.zone model.time)
+ second = String.fromInt (Time.toSecond model.zone model.time)
+ in
+ h1 [] [ text (hour ++ ":" ++ minute ++ ":" ++ second) ]
\ No newline at end of file