Fork of daniellemaywood.uk/gleam — Wasm codegen work
1<!--
2 SPDX-License-Identifier: Apache-2.0
3 SPDX-FileCopyrightText: 2020 The Gleam contributors
4-->
5
6# Changelog
7
8## v1.17.0 - 2026-06-02
9
10The release is dedicated to the memory of Chris Young, a man who inspired and
11believed in people. Without him, Gleam may not have ever existed.
12
13### Bug Fixes
14
15- Restrict custom documentation page `path` and `source` values so `gleam docs
16 build` cannot escape the docs output directory or project root.
17 ([evipepota](https://github.com/evipepota) and
18 [Louis Pilfold](https://github.com/lpil))
19
20- Stricter deserialisation rules for files internal the build directory to
21 reject corrupted data.
22 ([Abdelrahman Ahmed Aboelkasem](https://github.com/0x2face),
23 [Aly](https://github.com/spect3r1), and
24 [Louis Pilfold](https://github.com/lpil))
25
26- Restrict publication tarball creation so they cannot contain files from
27 outside the project root.
28 ([Abdelrahman Ahmed Aboelkasem](https://github.com/0x2face),
29 [Aly](https://github.com/spect3r1), and [Louis Pilfold](https://github.com/lpil))
30
31## v1.17.0-rc2 - 2026-06-01
32
33### Bug Fixes
34
35- Fixed a bug where the "Convert to case" code action would silently fail for
36 every inexhaustive `let` assignment in a module other than the first one.
37 ([John Downey](https://github.com/jtdowney))
38
39- Fixed a bug where the JavaScript code generator would not emit semicolon
40 after some expressions.
41 ([Andrey Kozhev](https://github.com/ankddev))
42
43- Fixed a bug where the JavaScript prelude's `BitArray$BitArray$data` FFI
44 function would throw an Error using the wrong class.
45 ([John Downey](https://github.com/jtdowney))
46
47- Fixed a bug where the JavaScript code generator could produce duplicate `let`
48 declarations for internal variables when a `case` expression was used as a
49 step in a pipeline.
50 ([Eyup Can Akman](https://github.com/eyupcanakman))
51
52- Fixed a bug where the JavaScript code generator would use wrong constructor
53 name in equality comparisons for imported variant with zero arguments and
54 import alias.
55 ([Andrey Kozhev](https://github.com/ankddev))
56
57## v1.17.0-rc1 - 2026-05-23
58
59### Compiler
60
61- The compiler now suggest public values from imported modules when the variable
62 is unknown. These values are suggested based on name and arity.
63
64 Considering this program:
65
66 ```gleam
67 import gleam/io
68
69 pub fn main() -> Nil {
70 println("Hello, World!")
71 }
72 ```
73
74 The compiler will display this error message:
75
76 ```text
77 error: Unknown variable
78 ┌─ /path/to/project/src/project.gleam:4:3
79 │
80 4 │ println("Hello, World!")
81 │ ^^^^^^^
82
83 The name `println` is not in scope here.
84 Did you mean one of these:
85
86 - io.println
87 ```
88
89 ([raphrous](https://github.com/realraphrous))
90
91- The inference of record update expressions is now more fault tolerant: if
92 there's an error in the record being updated, the compiler can still able to
93 analyse the fields that are being provided.
94 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
95
96- The inference of clause guards is now more fault tolerant: if there's an error
97 in a part of the guard expression, the compiler can still able to analyse the
98 rest of the guard rather than stopping at the first error.
99 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
100
101- It is now possible to use the `todo` keyword in constants, this will result in
102 an helpful error message rather than a syntax error.
103 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
104
105- The compiler now prints correctly qualified or aliased type names when
106 printing warnings. For example:
107
108 ```gleam
109 import user
110
111 pub fn main() {
112 user.to_string(todo)
113 |> io.println
114 }
115 ```
116
117 Will produce the following warning:
118
119 ```
120 warning: Todo found
121 ┌─ /src/warning/wrn.gleam:4:19
122 │
123 4 │ user.to_string(todo)
124 │ ^^^^ This code is incomplete
125
126 This code will crash if it is run. Be sure to finish it before
127 running your program.
128
129 Hint: I think its type is `user.User`.
130 ```
131
132 Notice how the type hint is correctly qualified for the module the warning is
133 raised in.
134 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
135
136- When writing a constant record with an empty arguments list the compiler will
137 no longer stop to analyse the entire module.
138 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
139
140- The compiler now normalizes remaining-bytes bit-array checks for the
141 JavaScript backend so `(bitSize - c) % 8 === 0` becomes `bitSize % 8 === 0`
142 when the constant offset `c` is congruent modulo 8. This produces more uniform
143 generated code for byte-aligned patterns.
144 ([Daniele Scaratti](https://github.com/lupodevelop))
145
146- The code generated for destructuring exhaustive patterns with `let` is now
147 less verbose on the JavaScript target.
148
149 ([Gavin Morrow](https://github.com/gavinmorrow))
150
151### Build tool
152
153- The `gleam dev` command now accepts the `--no-print-progress` flag. When this
154 flag is passed, no progress information is printed.
155 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
156
157- Tables in the generated docs now look better on smaller screens.
158 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
159
160- The comment in `manifest.toml` now instructs the user to include it in their
161 source control repository.
162 ([Louis Pilfold](https://github.com/lpil))
163
164- The `gleam deps outdated` command now always prints a summary showing how many
165 packages have newer versions available. For example:
166
167 ```txt
168 $ gleam deps outdated
169 1 of 12 packages have newer versions available.
170
171 Package Current Latest
172 ------- ------- ------
173 gleam_stdlib 0.70.0 0.71.0
174 ```
175
176 When no packages are outdated, only the summary line is printed:
177
178 ```txt
179 $ gleam deps outdated
180 0 of 12 packages have newer versions available.
181 ```
182
183 ([Daniele Scaratti](https://github.com/lupodevelop))
184
185- The package manager now has a specific error and automatic re-authentication
186 flow for when a Hex session has been revoked or has expired.
187 ([Sahil Upasane](https://github.com/404salad))
188
189- New packages are created requesting Erlang/OTP version 29 on GitHub actions.
190 ([Louis Pilfold](https://github.com/lpil))
191
192- `gleam publish` will now better discover Git repository in monorepos. This
193 improves suggestions to push a tag, if it doesn't exist.
194 ([Andrey Kozhev](https://github.com/ankddev))
195
196- The `gleam export escript` command has been added for the creation of
197 [escripts](https://www.erlang.org/doc/apps/erts/escript_cmd.html), BEAM
198 programs bundled into a single file.
199 ([Louis Pilfold](https://github.com/lpil))
200
201### Language server
202
203- The language server now offers a "Fill labels" code action on constants to
204 automatically fill in the missing labelled arguments from a record
205 constructor. For example:
206
207 ```gleam
208 pub type Pokemon {
209 Pokemon(number: Int, name: String, hp: Int)
210 }
211
212 pub const cleffa = Pokemon(number: 173)
213 ```
214
215 In this code snippet we haven't specified the `name` and `hp` fields, that's
216 an error! Triggering the "Fill labels" code action will result in the
217 following:
218
219 ```gleam
220 pub const cleffa = Pokemon(number: 173, name: todo, hp: todo)
221 ```
222
223 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
224
225- When hovering a record update expression, the language server can now show the
226 fields that are not being updated. For example:
227
228 ```gleam
229 pub type Person {
230 Person(name: String, age: Int)
231 }
232
233 pub fn happy_birthday_mom() {
234 let mom = Person(name: "Antonella", age: 60)
235 Person(..mom, age: 61)
236 // ^^^^^ Hovering this will show:
237 // Unchanged fields:
238 // - name
239 }
240 ```
241
242 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
243
244- The language server can now help with completions when typing a list's tail:
245
246 ```gleam
247 pub fn main() {
248 let things_i_like = ["Gleam", "Ice Cream"]
249 ["Dogs", ..t|]
250 // ^ Can now suggest a completion for `things_i_like`
251 }
252 ```
253
254 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
255
256- The language server can now help with completions when typing a record update:
257
258 ```gleam
259 pub type User {
260 User(name: String, likes: List(String))
261 }
262
263 pub fn set_name(user: User, name: String) -> User {
264 User(..u|)
265 // ^ Can now suggest a completion for `user`
266 }
267 ```
268
269 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
270
271- The language server now has a code action to remove a redundant record update.
272 For example:
273
274 ```gleam
275 pub type User {
276 User(name: String, likes: List(String))
277 }
278
279 pub fn main() {
280 let lucy = User(name: "Lucy", likes: ["Gleam", "Ice Cream"])
281 let jak = User(..lucy, name: "Jak", likes: ["Gleam", "Dogs"])
282 // ^^^^^^ This record update is not needed!
283 }
284 ```
285
286 This record update is not actually needed and will raise a warning, all fields
287 are already specified. Triggering the code action anywhere on the expression
288 will remove the unnecessary update:
289
290 ```gleam
291 pub type User {
292 User(name: String, likes: List(String))
293 }
294
295 pub fn main() {
296 let lucy = User(name: "Lucy", likes: ["Gleam", "Ice Cream"])
297 let jak = User(name: "Jak", likes: ["Gleam", "Dogs"])
298 }
299 ```
300
301 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
302
303- When using the wrong operator in a guard, the language server can now suggest
304 and apply an automatic fix. For example:
305
306 ```gleam
307 pub fn categorise() {
308 case pokemon {
309 Pokemon(name:, ..) if name == "rai" + "chu" -> todo
310 _ -> todo
311 }
312 }
313 ```
314
315 Gleam has no operator overloading, and the operator used to join strings is
316 `<>`, not `+`. The language server can automatically fix this common mistake.
317 Triggering the code action on the guard will replace `+` with `<>`.
318 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
319
320- The language server now presents quick fix code actions before refactoring
321 ones.
322 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
323
324- The language server now allows to further pattern match on a discard by
325 replacing it with the patterns it is discarding.
326 For example:
327
328 ```gleam
329 pub fn list_names(x: Result(List(String), Nil)) {
330 case x {
331 Error(Nil) -> io.println("no names")
332 Ok(_) -> todo
333 // ^ Triggering the code action here
334 }
335 }
336 ```
337
338 Triggering the code action will result in the following code:
339
340 ```gleam
341 pub fn list_names(x: Result(List(String), Nil)) {
342 case x {
343 Error(Nil) -> io.println("no names")
344 Ok([]) -> todo
345 Ok([first, ..rest]) -> todo
346 }
347 }
348 ```
349
350 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
351
352- The "Generate variant" code action now automatically adds an import to use the
353 generated variant if it is generated in a module from the different one.
354 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
355
356- The language server no longer shows completions for deprecated values from
357 dependencies.
358 ([Andrey Kozhev](https://github.com/ankddev))
359
360- The language server now offers a code action to create unknown modules
361 when an import is added for a module that doesn't exist.
362 For example, if `import wobble/woo` is added to `src/wiggle.gleam`,
363 then a code action to create `src/wobble/woo.gleam` will be presented
364 when triggered over `import wobble/woo`.
365 ([Cory Forsstrom](https://github.com/tarkah))
366
367- The language server now supports finding references when triggered on an
368 aliased import. For example, in the following snippet, moving the cursor
369 over `log` and triggering "find references" will show all references of
370 `io.println()`.
371
372 ```gleam
373 import gleam/io.{println as log}
374 fn main() {
375 log("Hello, world!")
376 //^^^ trigger here
377 }
378 ```
379
380 ([Gavin Morrow](https://github.com/gavinmorrow))
381
382- The language server now supports `textDocument/documentHighlight` anywhere
383 that `textDocument/references` is available.
384
385 For example, triggering it with the cursor over any instance of `vec` will
386 result in all of the instances of it being highlighted.
387
388 ```gleam
389 fn to_cartesian(vec) {
390 // ^^^
391 let x = vec.rho * cos(vec.theta)
392 // ^^^ ^^^
393 let y = vec.rho * sin(vec.theta)
394 // ^^^ ^^^
395 #(x, y)
396 }
397 ```
398
399 ([Gavin Morrow](https://github.com/gavinmorrow))
400
401### Formatter
402
403### Releases
404
405- A `gleam-licences.html` is now included with each release, detailing the
406 licences of the used dependencies.
407 ([Louis Pilfold](https://github.com/lpil))
408
409### Bug fixes
410
411- Fixed a bug where `gleam remove` would fail with a confusing File IO error
412 if `manifest.toml` didn't exist yet (e.g. in a freshly-created project or
413 after the manifest had been deleted).
414 ([Charlie Tonneslan](https://github.com/c-tonneslan))
415
416- Fixed a bug where the build tool would check for new major versions of a local
417 or git dependency on Hex when running `gleam update`.
418 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
419
420- Fixed a bug where the "pattern match on value" code action would generate
421 invalid code when used on a `let` assignment on the right hand side of another
422 `let` assignment.
423 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
424
425- Fixed a bug where the compiler wouldn't track the minimum required version
426 when using list prepending in constants.
427 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
428
429- Fixed a bug where the language server wouldn't let one extract record
430 constructors as variables.
431 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
432
433- Fixed a bug where the language server would suggest completions for values
434 from the language's prelude, even though their types were incompatible with
435 the current context.
436 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
437
438- Fixed a bug where the language server would suggest the "wrap in anonymous"
439 code action even when not hovering directly over a function.
440 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
441
442- Fixed a bug where the language server would suggest the "wrap in anonymous"
443 code action when hovering over a record update.
444 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
445
446- Fixed a bug where the compiler would generate invalid code for guards using
447 lists with a tail.
448 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
449
450- Fixed a bug where the language server would suggest the "convert to case" code
451 action even when not explicitly hovering an inexhaustive let assignment.
452 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
453
454- Fixed a bug where the language server would suggest the "add missing pattern"
455 code action even when not explicitly hovering an inexhaustive case expression.
456 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
457
458- Fixed a bug where the language server would suggest the "unqualify" code
459 action even when not explicitly hovering a qualified value.
460 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
461
462- Fixed a bug where the language server would suggest the "qualify" code
463 action even when not explicitly hovering an unqualified type or constructor.
464 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
465
466- Fixed a bug where the language server would suggest the "generate dynamic
467 decoder" code action even when not explicitly hovering a custom type.
468 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
469
470- Fixed a bug where the language server would suggest the "generate json
471 encoder" code action even when not explicitly hovering a custom type.
472 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
473
474- Fixed a bug where the language server would suggest the "missing type
475 parameter" code action even when not explicitly hovering a custom type.
476 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
477
478- Fixed a bug where the language server would suggest the "unwrap anonymous
479 function" code action even when not explicitly hovering a custom type.
480 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
481
482- Fixed a bug where the language server would suggest the "extract function"
483 code action even when selecting multiple branches of a case expression, or
484 patterns and guards of a case arm.
485 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
486
487- Fixed a bug where the compiler would not warn for ints over the safe
488 JavaScript limit in `BitArray` segments with a unit option.
489 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
490
491- Fixed a bug where the compiler would incorrectly warn for ints over the
492 safe JavaScript limit in `BitArray` byte segments that aren't ints.
493 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
494
495- Fixed a confusing error message when writing a constant bit array with a size
496 that is not a literal number.
497 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
498
499- Fixed a confusing error message when writing bit arrays with an invalid unit.
500 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
501
502- Fixed a confusing error message when writing a constant bit array with an
503 invalid segment.
504 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
505
506- Fixed a confusing error message when writing `@external` or `@deprecated`
507 annotations with arguments that are not string.
508 ([Giacomo Cavalieri](https://github.com/giacomocavalieri))
509
510- Fixed a bug where enabling `javascript.typescript_declarations` or
511 `javascript.source_maps` wouldn't generate their additional files unless the
512 build directory was manually deleted. The compiler now automatically rebuilds
513 the project when this configuration changes.
514 ([daniellionel01](https://github.com/daniellionel01))
515
516- Fixed a bug where using the `bytes` and `unit` options together on a bit array
517 segment could generate incorrect code on the JavaScript target.
518 ([Surya Rose](https://github.com/GearsDatapacks))
519
520- Fixed a bug where the JavaScript code generator could produce duplicate `let`
521 declarations for internal variables after a `case` expression whose subject
522 directly matches branch when existing variables with same exist in outer
523 scope.
524 ([Andrey Kozhev](https://github.com/ankddev))
525
526- Fixed a bug where `gleam publish` wrote the wrong application name into the
527 published package metadata for dependencies whose Hex package name differs
528 from their internal OTP application name. This caused Mix-based projects to
529 fail to build when they depended on Gleam packages with transitive
530 dependencies.
531 ([Logan Bresnahan](https://github.com/LoganBresnahan))
532
533- Fixed a bug where cli would fail to complete https connections from behind a
534 proxy with self-signed certificates. The cli now defaults to using system
535 trust stores for trusted CAs, allowing use in proxied network environments.
536 ([apsoras](https://github.com/apsoras))
537
538- Fixed a bug where the language server's "add missing patterns" code action
539 would not be offered when the cursor was on an inexhaustive `case` expression
540 if another inexhaustive `case` appeared earlier in the same module.
541 ([John Downey](https://github.com/jtdowney))