Gleam is a type safe and scalable language for the Erlang virtual machine and JavaScript runtimes. Today Gleam v1.1.0 has been published, just a month after v1.0.0. There’s loads of new stuff in this release, so take a look at some of what’s new!

Language server improvements

Productivity and developer experience is a first class concern to us, and in a modern language good editor support is an important part of the puzzle. To help Gleam has a built-in language server which is developed and maintained by the core team. The language server is relatively immature compared to the rest of the language’s tooling, and it is one of the main focuses for core development at the moment.

It has been improved in these ways:

Compilation batching

The language server is driven by messages sent by your editor each time a file is opened, code is edited, autocompletions are needed, and so on. When messages are received the language server runs the compiler (minus the codegen sections) to get information about the code.

The language server now batches theses messages intelligently, compiling when required rather than on every message. For example, if your editor rapidly sends several text edits and then a request for refactorings the language server will now apply all the edits to its in-memory filesystem overlay before compiling a single time. If you are using a faster computer you likely will see no difference, but if you’re using a slower computer or in a very large project you’ll no longer experience a delay before getting feedback from the language server.

Autocomplete imports

The language server will now autocomplete module names when writing import statements. Thank you Ameen Radwan for this improvement!

Neovim showing imports being autocompleted

Global goto definition

Gleam’s language server previously supported go-to definition for values defined in the top-level package, but with this release it also works for values defined in dependency packages too. Thank you Ameen Radwan again!

Bun support

Gleam compiles to JavaScript as well as Erlang, and there are multiple popular options for running JavaScript code on the command line. Gleam supports the NodeJS and Deno runtimes, and with v1.1.0 Bun support has been added too!

To use Bun either add javascript.runtime key to your gleam.toml, or add the --runtime=bun flag to your gleam run or gleam test command.

name = "app"
version = "1.0.0"
target = "javascript"

[javascript]
runtime = "bun"

Thank you gubsey for this feature.

Rebar support

Rebar3 is the standard Erlang build tool but some projects use the older build tool rebar (without the 3). Rebar3 has some amount of backwards compatibility with rebar and can build a typical rebar project, so with this release Gleam will now use rebar3 to build any rebar packages added as dependencies. This is enough to use all rebar packages we’ve found on the package manager so far.

Thank you Isaac Harris-Holt for this feature!

Formatter improvements

Giacomo Cavalieri the pretty-printing wizard has been hard at work improving the formatter and fixing bugs. One highlight is that the formatter will now sort groups of imports into alphabetical order automatically.

Juho Eerola also improved support for non-\n newlines in the formatter, causing them to be converted to \n rather than discarding them, which previously resulted in some empty lines being removed.

Clearer dependency requirements

Gleam uses the Hex package manager, and Hex specifies a syntax for version constraints. The syntax ~> 1.0, which means >= 1.0.0 and < 2.0.0, and Gleam would use this in your gleam.toml when adding a dependency with gleam add.

This syntax was very commonly misunderstood by people, and often would be confused for the ~> 1.0.0 syntax, which looks very similar but does something different and undesirable. To avoid this repeated confusion the longer and easier to understand syntax is now used instead.

JavaScript list optimisation

Julian Schurhammer identified and implemented an optimisation for prepending to a list on the JavaScript target. List prepending is extremely common in Gleam, so optimisations here have a big impact. Once applied running the standard library test suite went from ~3.0 seconds to ~2.4 seconds. Thank you Julian!

# before

2.98s user 0.37s system 135% cpu 2.471 total
2.85s user 0.37s system 133% cpu 2.409 total
3.00s user 0.39s system 134% cpu 2.516 total

# after

2.37s user 0.35s system 132% cpu 2.048 total
2.33s user 0.37s system 134% cpu 2.009 total
2.38s user 0.36s system 134% cpu 2.034 total

Internal types and values

Gleam has a concept of internal modules, which are modules that are only to be used from within the same package. With this release the @internal attribute can be used to make a type or value internal in a module that is otherwise not-internal. This may be helpful for exposing functionality so that it can be directly tested, while not making it part of the package’s public API.

Thank you Giacomo Cavalieri for this feature!

Dead code elimination

Gleam packages can be cross-target and work on both Erlang and JavaScript. These packages may have target specific dependencies which are only used on one target or the other.

The compiler now performs more aggressive dead-code elimination and will remove any code that is unreachable for the target that is currently being used.

Better package validation

Since v1.0.0 the number of Gleam packages has really taken off, new ones being published every day.

We don’t just want a healthy number of packages, we also want to ensure that Gleam packages are as high quality as possible. With this release we have some more things that we will be checking packages for before publishing, to catch common mistakes.

The gleam.toml project file includes the location of the source code repository for the package. Sometimes folks would make typos or forget to make the repository public, making the documentation’s links there unusable. When publishing Gleam will now make a request to this URL to ensure it loads successfully.

The Hex package manager has rules against name squatting, and empty packages published to reserve a name may be removed. Gleam now checks to make sure that blank packages are not published, and warns the publisher this is against the Hex terms of service.

Improved diagnostics

Gleam’s warnings and errors try to be as helpful as possible, hopefully making it clear how your code can be improved. Several improved error messages and new warnings have been added:

A case expression in Gleam can pattern match on multiple subjects at once. Folks may not be aware of this and may instead wrap multiple values in a redundant tuple as would be required in some other languages. This now causes a warning to be emitted:

An error about a tuple being redundant

In a future release the language server will have a code-action to remove this for you.

Another new warning is this one that is emitted when a literal expression or a side-effect free expression is not used. This helps the programmer catch dead code, and possibly also identify problems such as the missing <> in the example here:

A warning about an unusued value

And lastly, an example of an improved error. One mistake people unfamiliar with immutable linked lists might make is to attempt to append to a list using the list syntax. This syntax only works for prepending as prepending is fast, while appending is slow.

An error explaining why a spread is invalid

Thank you Giacomo Cavalieri for these improvements!

Improved tuple parsing

Tuples can be indexed into using the .0, .1, .2, etc syntax, but with previous versions of the parser indexing into nested tuples like tuple.0.2 would not parse successfully. Thank you to Nikita Sobolev for fixing this problem!

And the rest

That’s enough for this post, but there’s lots more. If you’d like to see all the changes for this release check out the changelog in the git repository.

Thanks

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

If you like Gleam consider sponsoring or asking your employer to sponsor Gleam development. I work full time on Gleam and your kind sponsorship is how I pay my bills!

Alternatively consider using our referral link for CodeCrafters, who have recently launched a course on implementing Redis in Gleam. Use your training budget to learn and to support Gleam too!

Thanks for reading, and I hope you enjoy Gleam v1 💜

Try Gleam