Changelog#
v1.16.0 - 2026-04-24#
v1.16.0-rc4 - 2026-04-22#
Build tool#
- Enabling JavaScript source map generation will now copy the source Gleam files to the output directory. This means that source maps will work in browsers without any further processing before being served. (Louis Pilfold)
Bug fixes#
- The
sourcesproperty of source map files now uses a relative URL to the source file. Previously it was using a filesystem path, which would not work in all JavaScript environments. (Louis Pilfold)
v1.16.0-rc3 - 2026-04-20#
Build tool#
- New Gleam packages are now generated requiring
>= 1.0.0ofgleam_stdlib. (Surya Rose)
Bug fixes#
- Fixed a bug where certain invalid programs would type check if they contained many mutually recursive functions. (Surya Rose)
v1.16.0-rc2 - 2026-04-14#
Build tool#
- Added
mts,cts,jsx,tsxto native file extensions so you can use external JavaScript code from files with these file extensions. (Niklas Kirschall)
Bug fixes#
-
manifest.tomlfiles with invalid package names now raise an error immediately when the file is parsed. (Louis Pilfold) -
Fixed a bug where the "Wrap in anonymous function" code action could be used in the body of a
useexpression (Giovanni Maria Zanchetta)
v1.16.0-rc1 - 2026-04-10#
Compiler#
-
The compiler now reports all errors and warnings it can find in modules that do not depend on each other, while previously it would always stop at the first module with an error. (Giacomo Cavalieri)
-
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 int 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/app/warning.gleam:3:20 │ 3 │ let <<_, number:152>> = sha │ ^^^ This segment is a 152-bit long int, 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 -
The compiler can now emit source maps when targeting JavaScript. This can be enabled in the
gleam.tomlwith thesource_mapssetting under thejavascriptsection. (Ameen Radwan)
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) -
gleam.tomlfiles with invalid dependency names now raise an error immediately when the file is parsed. (Louis Pilfold) -
Documentation for
--targetoption has been improved to include more details. (Andrey Kozhev)
Language server#
-
The language server will now show a diagnostic if you have a file open that could not be analysed due to its dependencies failing to compile. (Giacomo Cavalieri)
-
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.
-
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 function" code action can now be used to extract the right hand side of an assignment into its own function. For example, triggering it here:
pub fn personal_blog() { let introduction = html.main([], [ html.h1([], [html.text("Hello, world!")]), html.p([], [html.text("Gleam is cool")]) ]) //^^^ Triggering "extract function" on this expression html.body([introduction, blog_posts()]) }Would result in the following code:
pub fn personal_blog() { let introduction = function() html.body([introduction, blog_posts()]) } pub fn function() { html.main([], [ html.h1([], [html.text("Hello, world!")]), html.p([], [html.text("Gleam is cool")]) ]) } -
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 where some functions could be formatted to be longer than 80 characters. (Giacomo Cavalieri)
-
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 a bug where the compiler would not generate the correct code on the Erlang target for bit array string segments with the
utf16andutf32option. (Giacomo Cavalieri) -
Fixed the formatting of some errors' hints to properly wrap. (Giacomo Cavalieri)
-
Fixed a bug where box drawing characters would not use the same monospace font as all other characters inside code blocks in the generated documentation. (Giacomo Cavalieri)
-
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 the "Extract function" could generate invalid code when triggered on a use statement inside a block. (Giacomo Cavalieri)
-
Fixed a bug where constants referenced in a bit-array pattern's size option would report as unused. (Louis Pilfold)
-
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)