· via Hacker News – Front Page (hnrss.org)
Gleam v1.19.0 stops emitting Erlang source and targets abstract forms instead
Gleam v1.19.0 ships a rewritten Erlang backend that emits Erlang abstract forms rather than source code, cutting build times and making BEAM stack traces point to real Gleam lines.

Gleam v1.19.0 targets Erlang abstract forms instead of Erlang source
Gleam, a type-safe language that runs on the Erlang virtual machine and on JavaScript runtimes, has published version 1.19.0. According to the announcement on Gleam's website, which reached the Hacker News front page on 6 October, the headline change is an entirely rewritten Erlang code generator — one that no longer emits Erlang source code at all.
The rewrite was carried out by Giacomo Cavalieri over recent months and follows a fundamentally different design. Where earlier versions of Gleam produced Erlang source text that was then handed to the Erlang compiler, the new backend produces Erlang abstract forms: the metadata-annotated syntax tree that the Erlang compiler normally builds by running its own tokeniser and parser. Because abstract forms have a binary encoding based on Erlang's external term format, Gleam can load its generated code directly and skip the front half of the Erlang compiler entirely.
What the new backend buys
The announcement lists several concrete gains:
- Compiler performance: build times for Gleam projects targeting Erlang are significantly reduced.
- Accurate runtime metadata: location information now maps back to the original Gleam source rather than generated Erlang. Line numbers in BEAM crash reports and stack traces are exact, where previously they could be imprecise and only indicate the nearest function. The announcement adds that this metadata could enable full Gleam support in debuggers such as edb, though the team has not pursued that work itself.
- Cleaner compiler internals: the old generator was one of the oldest and most stable parts of the Gleam codebase but no longer matched the project's current standards and conventions; the replacement is described as raising the bar for the compiler as a whole.
The author also jokes that nobody can use "transpiler" as a pejorative for Gleam anymore, since the language now feeds an intermediate representation into the Erlang compiler rather than generating another language's source.
Benchmarks, with caveats
The performance claims are backed by a benchmark based on José Valim's langcompilebench project, which measures the time taken to compile 100 modules that each contain 100 functions returning a "hello world" string. The announcement is candid that such benchmarks are contrived and only exercise a small subset of each language's features.
The first stage of the rewrite shipped in v1.18.0, so the comparison pits v1.17.0 against v1.19.0 on full from-scratch builds without caching, and shows what the announcement calls a considerable improvement. Gleam's compilation is incremental, so typical development builds are faster still.
For context, the benchmark was extended with a range of other languages: the accompanying chart places Gleam compiling to both JavaScript and Erlang at the fast end, ahead of Go, Erlang, Java, Elixir, Elm, Rust, C# and TypeScript 7. The announcement cautions that this data alone is insufficient to draw hard conclusions about those languages.
Why not generate BEAM bytecode directly?
A natural question is why Gleam keeps the Erlang compiler in the loop at all. The announcement explains that BEAM bytecode, unlike Erlang source and abstract forms, is not a fixed target: each VM release can add or remove bytecode functionality, so a bytecode backend would require the Gleam team to track VM development closely with the Erlang maintainers and ship compiler updates in step with every VM release. It would also mean re-implementing decades of optimisations already present in the Erlang compiler, even with help from Gleam's static analysis.
Since Gleam is a community project funded by sponsorship and has a fraction of the resources of corporate- or institution-backed languages, abstract forms are described as the best trade-off of cost against benefit today. The announcement also notes that Elixir, Gleam's older sibling on the BEAM, compiles to Erlang via abstract forms as well.
JavaScript output also improved
The release is not only about Erlang. John Downey improved how pattern-matching decision trees compile to JavaScript: nested if statements are collapsed into single conditions with fewer intermediate variables, so a case expression matching a constructor with two specific fields now becomes one combined if instead of four levels of nesting. Interestingly, the announcement says this makes little to no difference to minified, gzipped bundle sizes, but leaves fewer branches for JavaScript engines to optimise.
The release also optimises list literals on the JavaScript target, where Gleam's immutable, persistent list type must be constructed as runtime data structures rather than written out as plain JavaScript arrays.
Why it matters
Changes to compiler architecture are usually invisible to users — until they aren't. By moving from source generation to abstract forms, Gleam gains faster builds and, more importantly for daily work, crash reports and stack traces that point at the exact Gleam line rather than an approximation. Aligning the toolchain with Elixir's proven approach, while explicitly declining the maintenance burden of emitting BEAM bytecode directly, shows a project making deliberate scope decisions. For a sponsorship-funded language competing for attention against far larger ecosystems, that restraint is part of the story: the team frames every decision as needing to hold up for years and decades.
- #gleam
- #erlang
- #compilers
- #beam
- #javascript