Skip to content
chornous.dev

Type two or more letters. Esc closes.

Index of sheets
Theme

Sheet 03 · Writing

All notes

Gleam 1.19 stops writing Erlang source: abstract forms, real line numbers and faster BEAM builds

Louis Pilfold announced Gleam v1.19.0 on October 5, 2026. The compiler now emits Erlang abstract forms instead of .erl source, which fixes line numbers in BEAM stack traces and cut a 10,000-function compile benchmark from 0.434 to 0.342.

Pl. 18 · pipeline drawing generated from the slug “gleam-1-19-erlang-abstract-forms”

Louis Pilfold published the Gleam v1.19.0 announcement on October 5, 2026, under the title "Gleam doesn't compile to Erlang source anymore." Giacomo Cavalieri rewrote the Erlang code generator, and Gleam now hands the Erlang compiler abstract forms, the syntax tree Erlang builds after parsing, in place of .erl text. A patch, v1.19.1, followed on October 7 with a fix for the export javascript-prelude and export typescript-prelude commands.

The post reached 300 points on Hacker News on October 7. The code generator got the headline, and the release also carries JavaScript, TypeScript and build tool work.

The old Erlang backend

Before 1.19, Gleam wrote Erlang source files. The location metadata in BEAM crash reports pointed at that generated Erlang, so a stack trace could show the wrong line and name no more than the nearest function.

With abstract forms, line numbers in stack traces and crash reports match your Gleam source. Pilfold also lists faster builds and a cleaner compiler as benefits.

The team considered emitting BEAM bytecode itself and rejected it. Bytecode changes between VM releases, so Gleam would carry the maintenance cost for every OTP version. Pilfold sees abstract forms as the best trade between cost and benefit, and Elixir targets them too.

The benchmark

Gleam on Erlang, v1.17
0.434
Gleam on Erlang, v1.19
0.342
Erlang itself
0.406

The numbers come from langcompilebench with 100 modules of 100 functions each, and lower is better. Gleam's JavaScript target scored 0.188, Go 0.195 and Rust 0.733. Pilfold calls the benchmarks contrived, so read them as direction. Your project's build time depends on how much of it goes to dependencies and how much to your own modules.

JavaScript output

John Downey flattened the nested if statements that case expressions used to produce into single conditions, so the generated code takes fewer branches. Cavalieri changed how Gleam builds short list literals. A three-element list used to go through an array conversion:

// before
const numbers = arrayToList([1, 2, 3])

// v1.19
const numbers = prepend(1, prepend(2, prepend(3, empty)))

Longer lists still use the array path.

TypeScript users get better declarations. For a generic custom type like Box(value) with Full(value) and Empty variants, the variant check keeps its type parameter where it can:

export function Box$isFull(value: any): value is Full<unknown>;

Tooling for mixed projects

Rodrigo Álvarez's build tool work targets teams that pull Gleam packages into Mix or rebar3 projects. Gleam now generates .app files for BEAM packages. gleam compile-package gained a --no-dev flag. export package-information and export package-interface can print to stdout, and the two prelude exports can write to a file.

The compiler also explains more mistakes: leftover merge conflict markers, operators Gleam doesn't have such as +=, a | inside a pattern, misplaced record update syntax, and cascading errors from a broken type alias.

Funding

Gleam runs on sponsorship. Pilfold writes that it is his sole income, and the post asks readers who use Gleam at work to sponsor the project.

This week

  1. Upgrade to v1.19.1 rather than v1.19.0 if you use the JavaScript or TypeScript prelude exports.
  2. Rebuild from clean and run your test suite on the BEAM target. The new code generator rewrote every Erlang module your project emits.
  3. Trigger a crash in a staging service and check that the stack trace points at the right Gleam line. If you wrote workarounds for the old line numbers in your error reporting, remove them.
  4. If you consume Gleam packages from Mix or rebar3, try the generated .app files and drop any hand-written ones.

No breaking language changes appear in the announcement, so the upgrade carries little risk for a pure Gleam project. Budget your time for the build tool changes if you mix Gleam into an Elixir or Erlang codebase.

Volodymyr Chornous