Gleam is a type safe and scalable language for the Erlang virtual machine (and JavaScript). Today Gleam v0.18.0 has been released, which includes the long awaited Gleam build tool.

Up until this point Gleam projects have mostly been using rebar3, the standard Erlang build tool. While it is a great build tool, rebar3 was not designed with Gleam in mind, and the ergonomics were sometimes surprising to newcomers. Overall it wasn’t a perfect fit for the language.

With the new Gleam build tool we have full control of the developer experience and can focus on making writing Gleam as productive and enjoyable as possible. We hope you like it!

Let’s take a look

The Gleam build tool is built into the Gleam binary with the compiler. Once you have downloaded Gleam v0.18.0 you have the build tool, there is nothing else to install.

As before new projects can be created with the gleam new command.

$ gleam new my_project
# Your Gleam project my_project has been successfully created.
# The project can be compiled and tested by running these commands:
# 
# 	cd my_project
# 	gleam test

The generated project looks like this:

$ tree
# ├── README.md
# ├── gleam.toml
# ├── src
# │   └── my_project.gleam
# └── test
#     └── my_project_test.gleam

The src directory contains your application code, and the test directory contains your test code.

Running the project

One aspect of rebar3 that people often found surprising was that the Erlang shell was the primary way to run your Gleam code. With Gleam v0.18 there’s now a familiar command that you can use instead.

$ cd my_project
$ gleam run
#   Resolving versions
# Downloading packages
#  Downloaded 2 packages in 0.01s
#   Compiling gleam_stdlib
#   Compiling gleeunit
#   Compiling my_project
#    Compiled in 1.85s
#     Running my_project.main
# Hello from my_project!

When the build tool runs it will automatically download and compile any dependency packages, compile your project, and then run the Erlang virtual machine to invoke main function of your project.

Dependencies are automatically sandboxed per-project, so there’s no need for virtual environments or other tools.

Testing

By default Gleam projects come preconfigured with gleeunit, a wrapper around Erlang’s test framework EUnit. The tests can be run with this command:

$ gleam test
#   Compiling my_project
#    Compiled in 0.24s
#     Running my_project_test.main
# .
# Finished in 0.008 seconds
# 1 tests, 0 failures

The gleam test command works similarly to the gleam run command and will download and compile dependencies as required. Because we had already run gleam run on this project and the dependency requirements had not changed, Gleam reused the cached results of the previous run. If a new requirement package is added or the requirements are changed in some other way Gleam will automatically determine what new code needs to be built and what can be reused.

// Inside test/my_project_test.gleam...
import gleeunit

pub fn main() {
  gleeunit.main() // Or your test code here!
}

While gleeunit is the default test framework, it is not mandatory. You can replace it with any code of your choosing, including test frameworks written in other BEAM languages such as Erlang or Elixir.

Adding dependencies

Gleam projects come with a gleam.toml file in which you specify project metadata, such as the project name, version, and any dependencies.

# Inside gleam.toml...
name = "my_project"
version = "0.1.0"

[dependencies]
gleam_stdlib = "~> 0.18"

[dev-dependencies]
gleeunit = "~> 0.5"

Dependency packages are specified in the dependencies section, with packages that are only required in the tests going in the dev-dependencies section.

You can add a new dependency package by editing either of these sections, but you can also use the gleam add command.

$ gleam add gleam_elli
#   Resolving versions
# Downloading packages
#  Downloaded 5 packages in 0.02s
#       Added gleam_elli v0.5.0

Here I’ve added the gleam_elli package. If I wanted to add it to the dev-dependencies section I could have run gleam add gleam_elli --dev.

The gleam_elli package provides bindings to Elli, an excellent web server written in Erlang. It uses the rebar3 build too, but this is no problem for the Gleam build tool, and it can be compiled all the same.

One of Gleam’s greatest strengths is that it can use code written in other BEAM languages, you are not limited to just Gleam. This gives the young Gleam ecosystem a big leg-up; its older siblings of Erlang and Elixir have a wealth of libraries ready for us to use.

For a full list of all the packages available see the website of the Hex package manager.

Standing on the shoulders of giants

As mentioned the Gleam build tool uses the existing Hex package manager and it’s ecosystem, rather than building a new one from scratch. We’re grateful to the Hex team for creating such a fantastic package manager, and for offering us plenty of advise on both how to use it as well as various tips for creating the Gleam build tool.

In the build tool we are using the state-of-the-art version resolution algorithm pubgrub, which was designed by Natalie Weizenbaum for pub, the package manager for the Dart language. It is well worth reading Natalie’s post linked above as it is a very cool and interesting piece of work. Thank you Natalie!

Pubgrub is quite a complicated algorithm to implement, but we were able to save a lot of time by using the Rust implementation, which serendipitously was first published while the Gleam build tool was being developed. Thank you to the maintainers Matthieu Pizenberg, Jacob Finkelman, Alex Tokarev, et al!

Lastly we would like to thank the creators of our other favourite build tools from the Rust, PureScript, JavaScript, Go, OCaml, Python, Elm, Elixir, and Erlang ecosystems. While they may not have contributed directly to Gleam, they have been a big inspiration, showing us what a good build tool should and should not do.

What’s next?

The Gleam build tool is out and ready to use, but we’ve still got lots to do.

Developer experience is extremely important to us, so we will continue to build upon and improve it in future releases. The features we’re most looking forward to are Language Server Protocol for IDE features in all editors, support for the the Gleam JavaScript compiler backend, and deployment related functionality.

How can I try it?

Instructions on how to install the latest version of Gleam can be found on the getting started page of the website. Once installed check out the language tour for an introduction to the language.

In addition to these changes this release also includes numerous other bug fixes and improvements. For all the details check out the changelog.

Supporting Gleam

If you would like to support me in making Gleam please consider sponsoring Gleam or asking your employer to sponsor Gleam. Every donation makes a difference, no matter how small, so thank you for your help.

⭐ Or alternatively give us a star on GitHub! ⭐

And thank you!

Gleam is made possible by the support of all the people who have sponsored and contributed to the project. Thank you all!

Thanks for reading! Have fun! 💜