Published 06 Dec, 2021 by Louis Pilfold
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.
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!
- Adam Bowen
- Adam Brodzinski
- Adam Mokan
- Adi Iyengar
- Al Dee
- alexander
- Alexander Koutmos
- Ali Farhadi
- Arnaud Berthomier
- Arno Dirlam
- Arto Bendiken
- Ben Marx
- Ben Myles
- Bruno Michel
- Cal Jacobson
- Chew Choon Keat
- Chris Lloyd
- Chris Young
- Christian Meunier
- clangley
- Clay
- Cole Lawrence
- Colin
- Conor Davidson
- Cristine Guadelupe
- d2weber
- Damir Vandic
- Dan
- Dan Mueller
- Dave Lucia
- David Armstrong Lewis
- David Bernheisel
- David Flanagan
- David-Klemenc
- Day Fisher
- Dennis Dang
- Drew Varner
- Dylan Lederle-Ensign
- Edgar Gomes
- Edon Gashi
- Eric Meadows-Jönsson
- Erik Terpstra
- Florian Kraft
- Gitpod
- Guilherme de Maio
- Herdy Handoko
- human154
- Ian Fisher
- Ian González
- Ingmar Gagen
- inoas
- Ivar Vong
- James MacAulay
- Jechol Lee (Trevor)
- Jeff Kreeftmeijer
- jiangplus
- Joe Corkerton
- John Doneth
- John Palgut
- Jonn
- josh rotenberg
- José Valim
- Jussi Norlund
- Kapp Technology
- Kieran Gill
- Lars Lillo Ulvestad
- Lars Wikman
- Marcel Lanz
- Marcin Puc
- Marius Kalvø
- Mark Markaryan
- Markus
- Memo
- Michael Chris Lopez
- Michael Jones
- Michael Kumm
- Michał Kowieski
- Michele Riva
- Mike Lapping
- Mike Roach
- Milton Mazzarri
- Nathaniel Knight
- Neil Lyons
- Nick Reynolds
- Nicklas Sindlev Andersen
- NineFX
- OldhamMade
- Ole Michaelis
- Parker Selbert
- Patrick Ryan
- Pete Jodo
- porkbrain
- Praveen Perera
- qingliangcn
- Raphael Megzari
- Raúl Chouza
- Redmar Kerkhoff
- Reio Piller
- René Klačan
- Robert Attard
- Robin Mattheussen
- Sam Aaron
- Sascha Wolf
- Saša Jurić
- Scott Wey
- Sean Jensen-Grey
- Sebastian Porto
- Shane Sveller
- Shunji Lin
- silicium14
- Simone Vittori
- SkunkWerks GmbH
- Strand Communications
- TakshakRamteke
- Terje Bakken
- Tim Buchwaldt
- Tom Schaefer
- Tomasz Kowal
- Tomochika Hara
- Tristan Cacqueray
- Tristan Sloughter
- Vincent Le Goff
- Vladimir Kuznetsov
- wangxing
- Wilson Silva
- Wojtek Mach
- woxtu
- YourMother-really
- Yu Matsuzawa
Thanks for reading! Have fun! 💜