Back to Gleam

Changelog

changelog/v1.15.md

1.16.014.7 KB
Original Source

Changelog

v1.15.0 - 2026-03-16

  • Fixed a bug where the language server wouldn't show the correct hover for some patterns. (Giacomo Cavalieri)

v1.15.0-rc2 - 2026-03-16

Bug fixes

  • Marked the bitSize and bitOffset fields of BitArray$BitArray TypeScript definition as optional. (acandoo)

  • Fixed invalid JavaScript code generation when ints or floats had prefixed 0s before and after an _ (e.g. 000_001). (Gavin Morrow)

v1.15.0-rc1 - 2026-03-04

Compiler

  • The compiler now reports an error when int and float binary operators are used incorrectly in case expression guards. (Adi Salimgereyev)

  • The compiler now supports string concatenation in clause guards:

    gleam
    case message {
      #(version, action) if version <> ":" <> action == "v1:delete" ->
        handle_delete()
      _ -> ignore()
    }
    

    (Adi Salimgereyev)

  • Improved the code generated on the Erlang target when dividing a Float number by the literal number 0.0. (Giacomo Cavalieri)

  • The compiler no longer shows the structure of internal types when displaying an "Inexhaustive patterns" error, making it harder to inadvertently rely on internal implementation details. (Giacomo Cavalieri)

  • The JavaScript prelude TypeScript API now contains the BitArray$isBitArray and BitArray$BitArray$data functions. (Louis Pilfold)

  • The type-checking JavaScript functions for Gleam data structure now use the value is TypeName TypeScript return type rather than boolean. (Louis Pilfold)

  • The compiler now shows better error message on passing unexpected labeled arguments by taking into account, whether it's a function or a constructor. (Andrey Kozhev)

Build tool

  • Upgraded actions/checkout from v4 to v6 in the GitHub Actions workflow used by gleam new. (Christian Widlund)

  • When adding a package that does not exist on Hex, the message is a bit friendlier. (Ameen Radwan)

  • The gleam.toml format is now consistent. The two sausage-case fields (dev-dependencies and tag-prefix) have been replaced by snake_case versions. Files using the old names will continue to work. (Louis Pilfold)

  • The password used for encrypting new local Hex API keys must now be at least 8 characters in length. (Louis Pilfold)

  • The gleam help add, gleam help deps, and gleam help docs commands have been improved with much more detailed documentation output. (Louis Pilfold)

  • When attempting to publish a package on Hex with an already taken name, the message is clearer. (vyacheslavhere)

  • The build tool will now refuse to publish any package that has the default README generated by the gleam new command. (Giacomo Cavalieri)

  • The build tool now uses OAuth and time-based one-time-passwords for authentication with Hex, improving security. Any legacy API tokens previously stored will be revoked after authenticating using OAuth. (Louis Pilfold)

  • The build tool will now refuse to publish any package that has no README, or an empty README. (Giacomo Cavalieri)

Language server

  • The language server now allows extracting the start of a pipeline into a variable. (Giacomo Cavalieri)

  • The language server now shows hover information when hovering over custom type definitions. (Giacomo Cavalieri)

  • The language server now shows hover information when hovering over a custom type's constructors. (Giacomo Cavalieri)

  • The language server is now smarter when producing autocompletions. Imagine you're updating your code to fully qualify the uses of the Json type:

    gleam
    pub fn payload() -> js|Json
    //                    ^ typing the module name
    

    Accepting the json.Json completion will now produce the correct json.Json annotation rather than generating invalid code: json.JsonJson. (Giacomo Cavalieri)

  • The language server now suggests completions for keywords like echo, panic, and todo. (Giacomo Cavalieri)

  • The "Add missing patterns" code action will insert a catch all pattern for internal types, making it harder to inadvertently rely on internal implementation details. (Giacomo Cavalieri)

  • The language server will no longer show completions for the fields of internal types outside the module they're defined in, making it harder to inadvertently rely on internal implementation details. (Giacomo Cavalieri)

  • The language server now suggests a quick-fix code action for when a custom type definition uses a type parameter in its variants that have not been declared in its header. (Andi Pabst)

  • The Extract function code action now provides more ergonomic/idiomatic refactorings when used on anonymous functions. (Hari Mohan)

  • It's now possible to find references and rename variables in string prefix patterns.

    gleam
    case wibble {
      "1" as digit <> rest -> digit <> rest
      //     ^^^^^    ^^^^
      // You can now trigger "Find references" and "Rename" from here
    }
    

    (Igor Castejón)

  • The language server now offers a rename for module when the cursor is placed over its import statement or when placed on its name or alias somewhere. For example,

    gleam
    import lustre/element
    import lustre/element/html
    import lustre/event
    
    fn view(model: Int) -> element.Element(Msg) {
      //                     ^  Renaming module to `el` here
      let count = int.to_string(model)
    
      html.div([], [
        html.button([event.on_click(Incr)], [element.text(" + ")]),
        html.p([], [element.text(count)]),
        html.button([event.on_click(Decr)], [element.text(" - ")]),
      ])
    }
    

    Using renaming when hovering on module name will would result in the following code:

    gleam
    import lustre/element as el
    import lustre/element/html
    import lustre/event
    
    fn view(model: Int) -> el.Element(Msg) {
      let count = int.to_string(model)
    
      html.div([], [
        html.button([event.on_click(Incr)], [el.text(" + ")]),
        html.p([], [el.text(count)]),
        html.button([event.on_click(Decr)], [el.text(" - ")]),
      ])
    }
    

    (Vladislav Shakitskiy)

  • The "Fill labels" code action now uses variables from scope when they match the label name and expected type, using shorthand syntax (name:) instead of name: todo.

    (Vladislav Shakitskiy)

  • The "Interpolate String" code action now lets the user "cut out" any portion of a string, regardless of whether it is a valid Gleam identifier or not. (Hari Mohan)

  • When interpolating an expression at the very start or the very end of a string, redundant empty strings are no longer added before/after the interpolated expression. (Hari Mohan)

  • The language server now performs best-effort zero value generation for decode.failure when using the Generate Dynamic Decoder code action. (Hari Mohan)

  • The Generate Dynamic Decoder and Generate To-JSON Function code action now generate a decoder and an encoder, respectively, for Nil values. (Hari Mohan)

  • The language server now supports renaming, go to definition, hover, and finding references from expressions in case clause guards. (Surya Rose)

  • The language server now supports textDocument/foldingRange, enabling folding for contiguous import blocks and multiline top-level definitions such as function bodies, custom types, constants, and type aliases.

    For example, this import block:

    gleam
    import gleam/int
    import gleam/list
    import gleam/string
    

    can now be folded in the editor to:

    gleam
    import gleam/int ...
    

    (Aayush Tripathi)

  • The function signature helper now displays original function definition generic names when arguments are unbound. For example, in this code:

    gleam
    pub fn wibble(x: something, y: fn() -> something, z: anything) { Nil }
    
    pub fn main() {
        wibble( )
            // ↑
    }
    

    will show a signature help

    gleam
    wibble(something, fn() -> something, anything)
    
    

    instead of

    gleam
    wibble(a, fn() -> a, b) -> Nil
    

    (Samuel Cristobal)

Formatter

  • The formatter no longer wraps multiple tuple or field access into a block. (Giacomo Cavalieri)

Bug fixes

  • The compiler now emits correctly-scoped JavaScript code for case expressions whose subjects directly match one of the branches. (Justin Lubin)

  • Fixed a bug where some bit array patterns would erroneously be marked as unreachable. (Giacomo Cavalieri)

  • Fixed a bug where the Gleam standard library's dict.each function would incorrectly be assumed to be pure. (Giacomo Cavalieri)

  • The compiler now correctly tracks the minimum required version for constant record updates to be >= 1.14.0. (Giacomo Cavalieri)

  • The compiler now correctly tracks the minimum required version for expressions in BitArrays' size option to be >= 1.12.0. (Giacomo Cavalieri)

  • Fixed a bug where the formatter would not properly format some function calls if the last argument was followed by a trailing comment. (Giacomo Cavalieri)

  • Fixed a bug where the compiler would generate invalid code on the JavaScript target when using a case expression as the right hand side of an equality check in an assert. (Giacomo Cavalieri)

  • Fixed a bug where the compiler would generate invalid code on the JavaScript target for some case expressions using clause guards. (Giacomo Cavalieri)

  • The formatter no longer stack overflows trying to format lists with many items. (Giacomo Cavalieri)

  • Fixed a bug where the formatter would not be able to consistently format a constant list with an @internal attribute. (Giacomo Cavalieri)

  • The "convert to pipe" code action now works on nested function calls as well, rather than always being applied to the outermost one. (Giacomo Cavalieri)

  • Fixed a bug where the compiler would not detect and reject duplicate modules in a project's dependencies. (Giacomo Cavalieri)

  • The language server no longer shows completions when typing a number. (Giacomo Cavalieri)

  • The language server no longer recommends the deprecated @target attribute. (Hari Mohan)

  • The compiler no longer crashes when trying to pattern match on a UtfCodepoint. (Hari Mohan)

  • Fixed a bug that would result in not being able to rename an aliased pattern. (Giacomo Cavalieri)

  • Fixed JavaScript codegen bug for assert when using && with comparison operators on the right side. (vyacheslavhere)

  • Added an error message when attempting to update packages that are not dependencies of the project, instead of failing silently. (Etienne Boutet, Vladislav Shakitskiy)

  • The build tool now doesn't perform code generation when exporting package interface. (Andrey Kozhev)

  • The "Extract constant" code action now correctly places new constant when function has documentation. For example,

    gleam
    /// Wibble does some wobbling
    pub fn wibble() {
      let x = "wobble"
      //  ^ Trigger "Extract constant" here
      x
    }
    

    Previously, it would incorrectly place it below doc comment:

    gleam
    /// Wibble does some wobbling
    const x = "wobble"
    
    pub fn wibble() {
      x
    }
    

    Now it will correctly place constant above doc comment:

    gleam
    const x = "wobble"
    
    /// Wibble does some wobbling
    pub fn wibble() {
      x
    }
    

    (Andrey Kozhev)

  • Fixed a bug where renaming would not work properly if there was an error in target file. (Surya Rose)

  • Fixed a bug where generics in custom types would not be properly generated when emitting TypeScript declarations. (Surya Rose)

  • Fixed a bug where dev dependencies would be compiled and included in production builds such as gleam export erlang-shipment. (John Downey)

  • Fixed a bug where the package cache would not properly be reset when a version of a package was replaced on Hex. (Surya Rose)

  • Fixed a crash (bad_generator) that could occur when a linked OTP process exits with a non-standard exit reason. (John Downey)

  • Fixed a bug where diagnostic about incorrect size and unit options would use incorrect error location. (Andrey Kozhev)

  • gleam add now adds correct constraints for pre-release versions. (Andrey Kozhev)

  • Fixed a bug where changes to a path dependency's own dependencies were not detected when rebuilding the root project, causing the compiler to report errors about missing modules. (daniellionel01)

  • Fixed a bug where the compiler would crash when type-checking record updates if the constructor definition has a positional field defined after labelled fields. (Hari Mohan)