How to create a simple photo gallery in ELM

A photo gallery is a collection or display of images, typically organized in a visually appealing manner, allowing users to view and navigate through multiple photographs or images. It’s often used on websites, applications, or physical spaces to showcase pictures, artwork, or visual content in an engaging and accessible way.

Creating a simple photo gallery in Elm involves several steps. Elm is a functional programming language for front-end web development that compiles to JavaScript. Here’s a step-by-step guide to creating a basic photo gallery using Elm:

Create Elm Application

To initialize a new Elm project, run the elm init command in the project folder via a terminal. This will create a elm.json file. Next, create a new Elm file, e.g., Main.elm. This will be the main entry point for our application.

Model

Define the model for the photo gallery. In this simple example, we can use a list of image URLs as our model.

-- Model
type alias Model =
{ photos : List String
, currentPhoto : Maybe String
}
initialModel : Model
initialModel =
{ photos =
[ "photo1.jpg"
, "photo2.jpg"
, "photo3.jpg"
]
, currentPhoto = Nothing
}

Update

Define messages that’ll be shown on the front end and the update function to handle the model’s logic. In the update function below, we check the msg and update the model accordingly. Let’s see the brief description of the Msg type and the update function below:

-- Msg
type Msg
= SelectPhoto String
| ClosePhoto
-- Update
update : Msg -> Model -> Model
update msg model =
case msg of
SelectPhoto photo ->
{ model | currentPhoto = Just photo }
ClosePhoto ->
{ model | currentPhoto = Nothing }

  • Line 3: We have a SelectPhoto String constructor that takes a String argument. This message is intended for selecting a photo, and the associated String represents the photo selected.

  • Line 4: We have another constructor function named ClosePhoto that doesn’t take any arguments. This message is for closing or deselecting a photo.

  • Line 7: We have the function’s type signature update : Msg -> Model -> Model , which specifies that it takes a Msg, the current Modeland returns a new Model.

  • Lines 10–11: SelectPhoto photo -> { model | currentPhoto = Just photo } shows that if the message is SelectPhoto with a photo argument, it updates the model’s currentPhoto field to Just photo. This means that it sets the selected photo, wrapping the photo string in a Just, which indicates the presence of a value.

  • Lines 13–14: ClosePhoto -> { model | currentPhoto = Nothing } shows if the message is ClosePhoto, it updates the model’s currentPhoto field to Nothing. This effectively clears the selected photo by setting the value to Nothing.

View

A function named view that takes a Model and returns an Html Msg. It’s responsible for rendering the view based on the Model:

-- View
view : Model -> Html Msg
view model =
let
renderPhoto photo =
div []
[ img [ src photo, onClick (SelectPhoto photo) ] []
]
currentPhotoView =
case model.currentPhoto of
Just photo ->
div []
[ img [ src photo ] []
, button [ onClick ClosePhoto ] [ text "Close" ]
]
Nothing ->
text "Select a photo to view."
in
div []
[ div [] (List.map renderPhoto model.photos)
, currentPhotoView
]
  • Line 5: We have a local function named renderPhoto that takes a photo and renders it as an img element.

  • Lines 10–19: We have a view named currentPhotoView that displays the currently selected photo. The case statement checks the model.currentPhoto, and generates the appropriate view based on whether a photo is present.

  • Lines 21–24: We have a div [] [...] block that creates the main structure for the view. The two elements within the div list are:

    • Line 22: div [] (List.map renderPhoto model.photos) creates a div containing all the photos from the model.photos list. It uses List.map to apply the renderPhoto function to each photo in the list, effectively displaying all the photos.

    • Line 23: currentPhotoView adds the section to view the currently selected photo, either showing the selected photo or a prompt to select a photo.

Main function

Define the main function to start the Elm application.

main =
Browser.sandbox { init = initialModel, update = update, view = view }

Compile Elm code

Compile the Elm code using the following command in the terminal. This will make a index.html file. Make sure to execute this command in the project directory.

elm make Main.elm

Open the index.html file in the browser, and you’ll see the images and a text that says, “Select a photo to view.”

Code

We’ve combined all the code snippets into one Main.elm file in the widget below. Let’s click the “Run” button to observe the functionality of our code:

{
    "type": "application",
    "source-directories": [
        "src"
    ],
    "elm-version": "0.19.0",
    "dependencies": {
        "direct": {
            "elm/browser": "1.0.1",
            "elm/core": "1.0.2",
            "elm/html": "1.0.0",
            "elm/time": "1.0.0",
            "elm/http": "2.0.0",
            "elm/json": "1.1.3"
        },
        "indirect": {
            "elm/url": "1.0.0",
            "elm/virtual-dom": "1.0.2",
            "elm/bytes": "1.0.8",
            "elm/file": "1.0.5"
        }
    },
    "test-dependencies": {
        "direct": {},
        "indirect": {}
    }
}
Photo gallery application

We’ve covered the essential steps, from setting up the project and defining the model to creating a basic user interface. We implemented a logic to create a simple photo gallery web page that previews the selected photo and closes it by clicking a button.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved