Back to Gleam

Changelog

changelog/v1.16.md

1.16.014.8 KB
Original Source

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 sources property 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.0 of gleam_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, tsx to native file extensions so you can use external JavaScript code from files with these file extensions. (Niklas Kirschall)

Bug fixes

  • manifest.toml files 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 use expression (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:

    gleam
    pub const viviparous_mammals = ["dog", "cat", "human"]
    
    pub const all_mammals = ["platypus", "echidna", ..viviparous_mammals]
    

    (Surya Rose)

  • 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:

    gleam
    pub type HashAlgorithm {
      @deprecated
      Md5
      Sha224
      Sha512
    }
    

    Will raise the following error:

    txt
    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/
    

    (Giacomo Cavalieri)

  • 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:

    gleam
    pub fn go(sha: BitArray) {
        let <<_, number:152>> = sha
        number
    }
    

    Will result in the following warning:

    txt
    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?
    

    (Giacomo Cavalieri)

  • 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.
    

    (Louis Pilfold)

  • The compiler now emits more efficient code when matching on single-character string prefixes on the JavaScript target. For example, the glance package 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
    

    (Surya Rose)

  • Compiler can now emit source maps when targeting JavaScript. This can be enabled in the gleam.toml with the source_maps setting under the javascript section. (Ameen Radwan)

Build tool

  • The gleam hex owner add command 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 publish command now has documentation for its options. (Giacomo Cavalieri)

  • The gleam hex retire command now accepts three flags --package, --version, and --reason instead of positional arguments. (Giacomo Cavalieri)

  • The gleam hex unretire command now accepts two flags --package, and --version instead of positional arguments. (Giacomo Cavalieri)

  • The gleam hex owner transfer command now accepts a flag --package instead of a positional argument. (Giacomo Cavalieri)

  • The gleam docs build command 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@11 will now produce:

    txt
    error: Dependency resolution failed
    
    The package `wisp` has no versions in the range >= 11.0.0 and < 12.0.0.
    

    (Giacomo Cavalieri)

  • The build tool will now suggest to create a module in the dev or test directory, 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.toml files with invalid dependency names now raise an error immediately when the file is parsed. (Louis Pilfold)

  • Documentation for --target option 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:

    gleam
    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:

    gleam
    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:

    gleam
    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:

    gleam
    pub fn words() {
      string
      |> function
      |> string.split(on: " ")
    }
    
    fn function(string: String) -> String {
      string
      |> string.lowercase
      |> string.replace(each: "jak", with: "lucy")
    }
    

    (Giacomo Cavalieri)

  • 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:

    gleam
    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:

    gleam
    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")])
      ])
    }
    

    (Giacomo Cavalieri)

  • 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:

    gleam
    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:

    gleam
    pub fn load_user(id: Int) -> Result(User, Error) {
      sql.find_by_id(id)
      |> result.map_error(CannotLoadUser)
    }
    

    (Giacomo Cavalieri)

  • 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:

    gleam
    #(#(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:

    gleam
    #(#(wibble, wobble), #(some_long_tuple, passed_as_last_argument))
    // after format:
    #(
      #(wibble, wobble),
      #(some_long_tuple, passed_as_last_argument)
    )
    

    (Giacomo Cavalieri)

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 - c to be evaluated as a - (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$data constructed a DataView with 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 utf16 and utf32 option. (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 let declarations for internal variables after a case expression 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$data constructed a DataView with 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)