Changelog#
v1.17.0 - 2026-06-02#
The release is dedicated to the memory of Chris Young, a man who inspired and believed in people. Without him, Gleam may not have ever existed.
Bug Fixes#
-
Restrict custom documentation page
pathandsourcevalues sogleam docs buildcannot escape the docs output directory or project root. (evipepota and Louis Pilfold) -
Stricter deserialisation rules for files internal the build directory to reject corrupted data. (Abdelrahman Ahmed Aboelkasem, Aly, and Louis Pilfold)
-
Restrict publication tarball creation so they cannot contain files from outside the project root. (Abdelrahman Ahmed Aboelkasem, Aly, and Louis Pilfold)
v1.17.0-rc2 - 2026-06-01#
Bug Fixes#
-
Fixed a bug where the "Convert to case" code action would silently fail for every inexhaustive
letassignment in a module other than the first one. (John Downey) -
Fixed a bug where the JavaScript code generator would not emit semicolon after some expressions. (Andrey Kozhev)
-
Fixed a bug where the JavaScript prelude's
BitArray$BitArray$dataFFI function would throw an Error using the wrong class. (John Downey) -
Fixed a bug where the JavaScript code generator could produce duplicate
letdeclarations for internal variables when acaseexpression was used as a step in a pipeline. (Eyup Can Akman) -
Fixed a bug where the JavaScript code generator would use wrong constructor name in equality comparisons for imported variant with zero arguments and import alias. (Andrey Kozhev)
v1.17.0-rc1 - 2026-05-23#
Compiler#
-
The compiler now suggest public values from imported modules when the variable is unknown. These values are suggested based on name and arity.
Considering this program:
import gleam/io pub fn main() -> Nil { println("Hello, World!") }The compiler will display this error message:
error: Unknown variable ┌─ /path/to/project/src/project.gleam:4:3 │ 4 │ println("Hello, World!") │ ^^^^^^^ The name `println` is not in scope here. Did you mean one of these: - io.println(raphrous)
-
The inference of record update expressions is now more fault tolerant: if there's an error in the record being updated, the compiler can still able to analyse the fields that are being provided. (Giacomo Cavalieri)
-
The inference of clause guards is now more fault tolerant: if there's an error in a part of the guard expression, the compiler can still able to analyse the rest of the guard rather than stopping at the first error. (Giacomo Cavalieri)
-
It is now possible to use the
todokeyword in constants, this will result in an helpful error message rather than a syntax error. (Giacomo Cavalieri) -
The compiler now prints correctly qualified or aliased type names when printing warnings. For example:
import user pub fn main() { user.to_string(todo) |> io.println }Will produce the following warning:
warning: Todo found ┌─ /src/warning/wrn.gleam:4:19 │ 4 │ user.to_string(todo) │ ^^^^ This code is incomplete This code will crash if it is run. Be sure to finish it before running your program. Hint: I think its type is `user.User`.Notice how the type hint is correctly qualified for the module the warning is raised in. (Giacomo Cavalieri)
-
When writing a constant record with an empty arguments list the compiler will no longer stop to analyse the entire module. (Giacomo Cavalieri)
-
The compiler now normalizes remaining-bytes bit-array checks for the JavaScript backend so
(bitSize - c) % 8 === 0becomesbitSize % 8 === 0when the constant offsetcis congruent modulo 8. This produces more uniform generated code for byte-aligned patterns. (Daniele Scaratti) -
The code generated for destructuring exhaustive patterns with
letis now less verbose on the JavaScript target.
Build tool#
-
The
gleam devcommand now accepts the--no-print-progressflag. When this flag is passed, no progress information is printed. (Giacomo Cavalieri) -
Tables in the generated docs now look better on smaller screens. (Giacomo Cavalieri)
-
The comment in
manifest.tomlnow instructs the user to include it in their source control repository. (Louis Pilfold) -
The
gleam deps outdatedcommand now always prints a summary showing how many packages have newer versions available. For example:$ gleam deps outdated 1 of 12 packages have newer versions available. Package Current Latest ------- ------- ------ gleam_stdlib 0.70.0 0.71.0When no packages are outdated, only the summary line is printed:
$ gleam deps outdated 0 of 12 packages have newer versions available. -
The package manager now has a specific error and automatic re-authentication flow for when a Hex session has been revoked or has expired. (Sahil Upasane)
-
New packages are created requesting Erlang/OTP version 29 on GitHub actions. (Louis Pilfold)
-
gleam publishwill now better discover Git repository in monorepos. This improves suggestions to push a tag, if it doesn't exist. (Andrey Kozhev) -
The
gleam export escriptcommand has been added for the creation of escripts, BEAM programs bundled into a single file. (Louis Pilfold)
Language server#
-
The language server now offers a "Fill labels" code action on constants to automatically fill in the missing labelled arguments from a record constructor. For example:
pub type Pokemon { Pokemon(number: Int, name: String, hp: Int) } pub const cleffa = Pokemon(number: 173)In this code snippet we haven't specified the
nameandhpfields, that's an error! Triggering the "Fill labels" code action will result in the following:pub const cleffa = Pokemon(number: 173, name: todo, hp: todo) -
When hovering a record update expression, the language server can now show the fields that are not being updated. For example:
pub type Person { Person(name: String, age: Int) } pub fn happy_birthday_mom() { let mom = Person(name: "Antonella", age: 60) Person(..mom, age: 61) // ^^^^^ Hovering this will show: // Unchanged fields: // - name } -
The language server can now help with completions when typing a list's tail:
pub fn main() { let things_i_like = ["Gleam", "Ice Cream"] ["Dogs", ..t|] // ^ Can now suggest a completion for `things_i_like` } -
The language server can now help with completions when typing a record update:
pub type User { User(name: String, likes: List(String)) } pub fn set_name(user: User, name: String) -> User { User(..u|) // ^ Can now suggest a completion for `user` } -
The language server now has a code action to remove a redundant record update. For example:
pub type User { User(name: String, likes: List(String)) } pub fn main() { let lucy = User(name: "Lucy", likes: ["Gleam", "Ice Cream"]) let jak = User(..lucy, name: "Jak", likes: ["Gleam", "Dogs"]) // ^^^^^^ This record update is not needed! }This record update is not actually needed and will raise a warning, all fields are already specified. Triggering the code action anywhere on the expression will remove the unnecessary update:
pub type User { User(name: String, likes: List(String)) } pub fn main() { let lucy = User(name: "Lucy", likes: ["Gleam", "Ice Cream"]) let jak = User(name: "Jak", likes: ["Gleam", "Dogs"]) } -
When using the wrong operator in a guard, the language server can now suggest and apply an automatic fix. For example:
pub fn categorise() { case pokemon { Pokemon(name:, ..) if name == "rai" + "chu" -> todo _ -> todo } }Gleam has no operator overloading, and the operator used to join strings is
<>, not+. The language server can automatically fix this common mistake. Triggering the code action on the guard will replace+with<>. (Giacomo Cavalieri) -
The language server now presents quick fix code actions before refactoring ones. (Giacomo Cavalieri)
-
The language server now allows to further pattern match on a discard by replacing it with the patterns it is discarding. For example:
pub fn list_names(x: Result(List(String), Nil)) { case x { Error(Nil) -> io.println("no names") Ok(_) -> todo // ^ Triggering the code action here } }Triggering the code action will result in the following code:
pub fn list_names(x: Result(List(String), Nil)) { case x { Error(Nil) -> io.println("no names") Ok([]) -> todo Ok([first, ..rest]) -> todo } } -
The "Generate variant" code action now automatically adds an import to use the generated variant if it is generated in a module from the different one. (Giacomo Cavalieri)
-
The language server no longer shows completions for deprecated values from dependencies. (Andrey Kozhev)
-
The language server now offers a code action to create unknown modules when an import is added for a module that doesn't exist. For example, if
import wobble/woois added tosrc/wiggle.gleam, then a code action to createsrc/wobble/woo.gleamwill be presented when triggered overimport wobble/woo. (Cory Forsstrom) -
The language server now supports finding references when triggered on an aliased import. For example, in the following snippet, moving the cursor over
logand triggering "find references" will show all references ofio.println().import gleam/io.{println as log} fn main() { log("Hello, world!") //^^^ trigger here } -
The language server now supports
textDocument/documentHighlightanywhere thattextDocument/referencesis available.For example, triggering it with the cursor over any instance of
vecwill result in all of the instances of it being highlighted.fn to_cartesian(vec) { // ^^^ let x = vec.rho * cos(vec.theta) // ^^^ ^^^ let y = vec.rho * sin(vec.theta) // ^^^ ^^^ #(x, y) }
Formatter#
Releases#
- A
gleam-licences.htmlis now included with each release, detailing the licences of the used dependencies. (Louis Pilfold)
Bug fixes#
-
Fixed a bug where
gleam removewould fail with a confusing File IO error ifmanifest.tomldidn't exist yet (e.g. in a freshly-created project or after the manifest had been deleted). (Charlie Tonneslan) -
Fixed a bug where the build tool would check for new major versions of a local or git dependency on Hex when running
gleam update. (Giacomo Cavalieri) -
Fixed a bug where the "pattern match on value" code action would generate invalid code when used on a
letassignment on the right hand side of anotherletassignment. (Giacomo Cavalieri) -
Fixed a bug where the compiler wouldn't track the minimum required version when using list prepending in constants. (Giacomo Cavalieri)
-
Fixed a bug where the language server wouldn't let one extract record constructors as variables. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest completions for values from the language's prelude, even though their types were incompatible with the current context. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest the "wrap in anonymous" code action even when not hovering directly over a function. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest the "wrap in anonymous" code action when hovering over a record update. (Giacomo Cavalieri)
-
Fixed a bug where the compiler would generate invalid code for guards using lists with a tail. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest the "convert to case" code action even when not explicitly hovering an inexhaustive let assignment. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest the "add missing pattern" code action even when not explicitly hovering an inexhaustive case expression. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest the "unqualify" code action even when not explicitly hovering a qualified value. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest the "qualify" code action even when not explicitly hovering an unqualified type or constructor. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest the "generate dynamic decoder" code action even when not explicitly hovering a custom type. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest the "generate json encoder" code action even when not explicitly hovering a custom type. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest the "missing type parameter" code action even when not explicitly hovering a custom type. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest the "unwrap anonymous function" code action even when not explicitly hovering a custom type. (Giacomo Cavalieri)
-
Fixed a bug where the language server would suggest the "extract function" code action even when selecting multiple branches of a case expression, or patterns and guards of a case arm. (Giacomo Cavalieri)
-
Fixed a bug where the compiler would not warn for ints over the safe JavaScript limit in
BitArraysegments with a unit option. (Giacomo Cavalieri) -
Fixed a bug where the compiler would incorrectly warn for ints over the safe JavaScript limit in
BitArraybyte segments that aren't ints. (Giacomo Cavalieri) -
Fixed a confusing error message when writing a constant bit array with a size that is not a literal number. (Giacomo Cavalieri)
-
Fixed a confusing error message when writing bit arrays with an invalid unit. (Giacomo Cavalieri)
-
Fixed a confusing error message when writing a constant bit array with an invalid segment. (Giacomo Cavalieri)
-
Fixed a confusing error message when writing
@externalor@deprecatedannotations with arguments that are not string. (Giacomo Cavalieri) -
Fixed a bug where enabling
javascript.typescript_declarationsorjavascript.source_mapswouldn't generate their additional files unless the build directory was manually deleted. The compiler now automatically rebuilds the project when this configuration changes. (daniellionel01) -
Fixed a bug where using the
bytesandunitoptions together on a bit array segment could generate incorrect code on the JavaScript target. (Surya Rose) -
Fixed a bug where the JavaScript code generator could produce duplicate
letdeclarations for internal variables after acaseexpression whose subject directly matches branch when existing variables with same exist in outer scope. (Andrey Kozhev) -
Fixed a bug where
gleam publishwrote the wrong application name into the published package metadata for dependencies whose Hex package name differs from their internal OTP application name. This caused Mix-based projects to fail to build when they depended on Gleam packages with transitive dependencies. (Logan Bresnahan) -
Fixed a bug where cli would fail to complete https connections from behind a proxy with self-signed certificates. The cli now defaults to using system trust stores for trusted CAs, allowing use in proxied network environments. (apsoras)
-
Fixed a bug where the language server's "add missing patterns" code action would not be offered when the cursor was on an inexhaustive
caseexpression if another inexhaustivecaseappeared earlier in the same module. (John Downey)