Changelog#
Unreleased#
Compiler#
-
The compiler now supports list prepending in constants. For example:
pub const viviparous_mammals = ["dog", "cat", "human"] pub const all_mammals = ["platypus", "echidna", ..viviparous_mammals] -
The analysis of record update expressions is now fault tolerant, meaning the compiler will no longer stop reporting errors at the first invalid field it finds. (Giacomo Cavalieri)
-
The compiler now shows a better error message when trying to use the record update syntax with variants that have no labelled fields. (Giacomo Cavalieri)
-
The error message for invalid deprecated attributes with no deprecation message has been improved. For example, the following code:
pub type HashAlgorithm { @deprecated Md5 Sha224 Sha512 }Will raise the following error:
error: Syntax error ┌─ /src/parse/error.gleam:3:3 │ 3 │ @deprecated │ ^^^^^^^^^^^ A deprecation attribute must have a string message. See: https://tour.gleam.run/functions/deprecations/ -
The compiler now raises a warning on the JavaScript target when defining an integer segment with a size higher than 52 bits. For example, this code:
pub fn go(sha: BitArray) { let <<_, number:152>> = sha number }Will result in the following warning:
warning: Truncated bit array segment ┌─ /src/warning/wrn.gleam:3:20 │ 3 │ let <<_, number:152>> = sha │ ^^^ This segment is a 152-bit long integer, but on the JavaScript target numbers have at most 52 bits. It would be truncated to its first 52 bits. Hint: Did you mean to use the `bytes` segment option? -
The compiler now emits a helpful error message when source code contains an invalid unicode character that looks similar to a correct character.
error: Syntax error ┌─ /src/parse/error.gleam:1:20 │ 1 │ pub fn main() { #(1‚ 2) } │ ^ Unexpected character This looks like ascii comma, but it is actually the unicode low single comma quotation mark. -
The compiler now emits more efficient code when matching on single-character string prefixes on the JavaScript target. For example, the
glancepackage is now nearly 30% faster on the JavaScript target:# before: min: 10.8ms, max: 365.82ms, median: 14.74ms, mean: 14.76ms warmup: 100/1.5s, total post-warmup: 1000/14.76s # after: min: 8.96ms, max: 143.76ms, median: 10.72ms, mean: 11.06ms warmup: 100/1.24s, total post-warmup: 1000/11.06s
Build tool#
-
The
gleam hex owner addcommand has been added, which allows adding owners to the package. (Niklas Kirschall) -
When publishing, the package manager now uses the full term instead of the shorthand "MFA" in the prompt and error message. (Luka Ivanović)
-
When Hex rejects publish with error 422, show error message instead of defaulting to "can only modify a release up to one hour after publication" (David Matz)
-
The
gleam publishcommand now has documentation for its options. (Giacomo Cavalieri) -
The
gleam hex retirecommand now accepts three flags--package,--version, and--reasoninstead of positional arguments. (Giacomo Cavalieri) -
The
gleam hex unretirecommand now accepts two flags--package, and--versioninstead of positional arguments. (Giacomo Cavalieri) -
The
gleam hex owner transfercommand now accepts a flag--packageinstead of a positional argument. (Giacomo Cavalieri) -
The
gleam docs buildcommand no longer recompiles all the project's dependencies every single time it is run. (Giacomo Cavalieri) -
The build tool now produces a nicer error message when trying to add a package's version that doesn't exist. For example, running
gleam add wisp@11will now produce:error: Dependency resolution failed The package `wisp` has no versions in the range >= 11.0.0 and < 12.0.0. -
The build tool will now suggest to create a module in the
devortestdirectory, if that missing module is a dev module or a test module respectively. (Andrey Kozhev) -
Now all options with declared variants have consistent representation of possible values. (Andrey Kozhev)
-
New Gleam packages are generated requiring >= 0.70.0 of
gleam_stdlib. (Louis Pilfold) -
Documentation for
--targetoption has been improved to include more details. (Andrey Kozhev)
Language server#
-
The language server now offers code actions to wrap a function reference in an anonymous function, or to remove a trivial anonymous function, leaving its contents. For example:
pub fn main() { [-1, -2, -3] |> list.map(fn(a) { int.absolute_value(a) }) // ^^ Activating the "Remove anonymous function" // code action here }would result in:
pub fn main() { [-1, -2, -3] |> list.map(int.absolute_value) }while the other action would reverse the change. (Eli Treuherz)
-
The "extract function" code action can now be used in pipelines to extract a part of one into a function. For example, triggering it here:
pub fn words() { string |> string.lowercase // ^^^ |> string.replace(each: "jak", with: "lucy") // ^^^ selecting these two steps of the pipeline |> string.split(on: " ") }Would result in the following code:
pub fn words() { string |> function |> string.split(on: " ") } fn function(string: String) -> String { string |> string.lowercase |> string.replace(each: "jak", with: "lucy") } -
The "extract variable" code action can now pick better names for variables in case branches and blocks, ignoring unrelated names of variables in other branches. (Giacomo Cavalieri)
-
The language server now has a code action to replace a
_in a type annotation with the corresponding type. For example:pub fn load_user(id: Int) -> Result(_, Error) { // ^ // Triggering the code action here sql.find_by_id(id) |> result.map_error(CannotLoadUser) }Triggering the code action over the
_will result in the following code:pub fn load_user(id: Int) -> Result(User, Error) { sql.find_by_id(id) |> result.map_error(CannotLoadUser) } -
The language server now shows completions for the labelled argument of a record when writing a record update. (Giacomo Cavalieri)
-
The language server no longer shows completions for values when editing a qualified type. (Giacomo Cavalieri)
Formatter#
-
The formatter no longer moves comments out of type annotations. (Giacomo Cavalieri)
-
The formatting of long nested tuples has been improved. Previously the formatter would split only the last tuple:
#(#(wibble, wobble), #(some_long_tuple, passed_as_last_argument)) // after format: #(#(wibble, wobble), #( some_long_tuple, passed_as_last_argument ))But now it favours first splitting each element onto its own line:
#(#(wibble, wobble), #(some_long_tuple, passed_as_last_argument)) // after format: #( #(wibble, wobble), #(some_long_tuple, passed_as_last_argument) )
Bug fixes#
-
Fixed a bug that would result in not being able to publish a package if some non-ASCII characters were used in field names other than
description. (Niklas Kirschall) -
Fixed a bug where arithmetic operators in bit array size expressions were not left-associative, causing
a - b - cto be evaluated asa - (b - c)instead of(a - b) - c. (Daniele Scaratti) -
Fixed a bug where the compiler would crash when trying to read the cache for modules containing large constants. (Surya Rose)
-
Fixed a bug where
BitArray$BitArray$dataconstructed aDataViewwith incorrect byte length instead of the slice's actual size, causing sliced bit arrays to include extra bytes from the underlying buffer on JavaScript. (John Downey) -
The compiler now parses UTF-8 source files with a byte-order mark correctly, instead of raising an error. (Lucy McPhail)
-
Fixed a bug where semicolons would not be properly added to pipelines in generated JavaScript code, leading to runtime errors in certain circumstances. (Surya Rose)
-
Fixed the formatting of some errors' hints to properly wrap. (Giacomo Cavalieri)
-
Fixed a bug where the JavaScript code generator could produce duplicate
letdeclarations for internal variables after acaseexpression whose subject directly matches one of the branches. (Eyup Can Akman)
v1.15.1 - 2026-03-17#
Bug fixes#
-
Fixed a bug where
BitArray$BitArray$dataconstructed aDataViewwith offset 0 instead of the slice's actual byte offset, causing sliced bit arrays to read from the wrong position in the underlying buffer on JavaScript. (John Downey) -
Fixed a bug where the "Add missing type parameter" code action could be triggered on types that do not exist instead of type variables. (Giacomo Cavalieri)
-
Fixed a bug where the "Add missing patterns" code action could end up deleting comments inside an incomplete case expression. (Giacomo Cavalieri)
-
Fixed a bug where some functions could be formatted to be longer than 80 characters. (Giacomo Cavalieri)