Skip to content

Releases: elixir-lang/elixir

v1.19.0-rc.2

07 Oct 16:41
Compare
Choose a tag to compare
v1.19.0-rc.2 Pre-release
Pre-release

1. Enhancements

Elixir

  • [Regex] Raise error message when regexes are used as default values in struct fields for compatibility with Erlang/OTP 28
  • [Registry] Add key-based partitioning of duplicate registries

2. Bug fixes

Elixir

  • [Kernel] Address issue with type checking not completing on protocol consolidation

ExUnit

  • [ExUnit] Do not crash on empty test unit groups

Mix

  • [mix help] Add mix help app:APP
  • [mix test] Fix module preloading in mix test --slowest-modules=N

v1.19-latest

07 Jun 18:18
Compare
Choose a tag to compare

Automated release for latest v1.19.

main-latest

17 Sep 07:21
Compare
Choose a tag to compare

Automated release for latest main.

v1.19.0-rc.1

05 Oct 13:35
Compare
Choose a tag to compare
v1.19.0-rc.1 Pre-release
Pre-release

1. Enhancements

Elixir

  • [Kernel] Raise when U+2028 and U+2029 characters are present in comments and strings to avoid line spoofing attacks
  • [Kernel] Include the line for the previous clause in errors/warnings related to conflicts between defaults on function definitions
  • [Macro] Add __escape__/1 callback so structs can escape references and other runtime data types in Macro.escape/1
  • [OptionParser] Support the :regex type
  • [OptionParser] Enhance parsing error to display available options
  • [String] Update to Unicode 17.0.0

ExUnit

  • [ExUnit] Set a process label for each test

Logger

  • [Logger] Accept any enumerable in Logger.metadata/1

Mix

  • [mix format] Add options to mix format to allow excluding of files
  • [mix test] Add --name-pattern option to mix test
  • [Mix.install/2] Support the :compilers option

2. Bug fixes

Elixir

  • [Code] Return error on invalid unicode sequences in Code.string_to_quoted/2 instead of raising
  • [Code] Properly handle column annotation for in in not in expressions
  • [Enum] Fix infinite loop on Enum.take/2 with negative index on empty enumerable
  • [Inspect] Inspect ill-formed structs as maps
  • [Kernel] Properly increment metadata newline when ? is followed by a literal newline character

ExUnit

  • [ExUnit.Assertions] Fix order in ExUnit results when listing pinned variables
  • [ExUnit.Assertions] Raise if attempting to raise an assertion error with invalid message (not a binary)

IEx

  • [IEx] Abort pipelines when there is an error in any step along the way

Mix

  • [mix compile] Fix bug where reverting changes to an external resource (such as HEEx template) after a compilation error would make it so the source module would not be compiled
  • [mix compile] Avoid failures when locking compilation across different users
  • [mix compile] Fix race condition when renaming files used by the compilation lock
  • [mix test] Prevent mix test from overriding :failures_manifest_path option

3. Hard deprecations

Elixir

  • [Code] Warn if line-break characters outside of \r and \r\n are found in strings according to UX#55. This warning will be fast-tracked into an error for security reasons in Elixir v1.20, following a similar rule to bidirectional control characters. They will already raise if found in comments

v1.18-latest

10 Dec 14:02
Compare
Choose a tag to compare

Automated release for latest v1.18.

v1.19.0-rc.0

09 Jun 11:03
Compare
Choose a tag to compare
v1.19.0-rc.0 Pre-release
Pre-release

Type system improvements

Type checking of protocol dispatch and implementations

This release also adds type checking when dispatching and implementing protocols.

For example, string interpolation in Elixir uses the String.Chars protocol. If you pass a value that does not implement said protocol, Elixir will now emit a warning accordingly.

Here is an example passing a range, which cannot be converted into a string, to an interpolation:

defmodule Example do def my_code(first..last//step = range) do "hello #{range}" end end

the above emits the following warnings:

warning: incompatible value given to string interpolation: data it has type: %Range{first: term(), last: term(), step: term()} but expected a type that implements the String.Chars protocol, it must be one of: dynamic( %Date{} or %DateTime{} or %NaiveDateTime{} or %Time{} or %URI{} or %Version{} or %Version.Requirement{} ) or atom() or binary() or float() or integer() or list(term()) 

Warnings are also emitted if you pass a data type that does not implement the Enumerable protocol as a generator to for-comprehensions:

defmodule Example do def my_code(%Date{} = date) do for(x <- date, do: x) end end

will emit:

warning: incompatible value given to for-comprehension: x <- date it has type: %Date{year: term(), month: term(), day: term(), calendar: term()} but expected a type that implements the Enumerable protocol, it must be one of: dynamic( %Date.Range{} or %File.Stream{} or %GenEvent.Stream{} or %HashDict{} or %HashSet{} or %IO.Stream{} or %MapSet{} or %Range{} or %Stream{} ) or fun() or list(term()) or non_struct_map() 

Type checking and inference of anonymous functions

Elixir v1.19 can now type infer and type check anonymous functions. Here is a trivial example:

defmodule Example do def run do fun = fn %{} -> :map end fun.("hello") end end

The example above has an obvious typing violation, as the anonymous function expects a map but a string is given. With Elixir v1.19, the following warning is now printed:

 warning: incompatible types given on function application: fun.("hello") given types: binary() but function has type: (dynamic(map()) -> :map) typing violation found at: │ 6 │ fun.("hello") │ ~ │ └─ mod.exs:6:8: Example.run/0 

Function captures, such as &String.to_integer/1, will also propagate the type as of Elixir v1.19, arising more opportunity for Elixir's type system to catch bugs in our programs.

Acknowledgements

The type system was made possible thanks to a partnership between CNRS and Remote. The development work is currently sponsored by Fresha, Starfish*, and Dashbit.

Faster compile times in large projects

This release includes two compiler improvements that can lead up to 4x faster builds in large codebases.

While Elixir has always compiled the given files in project or a dependency in parallel, the compiler would sometimes be unable to use all of the machine resources efficiently. This release addresses two common limitations, delivering performance improvements that scale with codebase size and available CPU cores.

Code loading bottlenecks

Prior to this release, Elixir would load modules as soon as they were defined. However, because the Erlang part of code loading happens within a single process (the code server), this would make it a bottleneck, reducing the amount of parallelization, especially on large projects.

This release makes it so modules are loaded lazily. This reduces the pressure on the code server, making compilation up to 2x faster for large projects, and also reduces the overall amount of work done during compilation.

Implementation wise, the parallel compiler already acts as a mechanism to resolve modules during compilation, so we built on that. By making sure the compiler controls both module compilation and module loading, it can also better guarantee deterministic builds.

The only potential regression in this approach happens if you have a module, which is used at compile time and defines an @on_load callback (typically used for NIFs) that invokes another modules within the same project. For example:

defmodule MyLib.SomeModule do @on_load :init def init do MyLib.AnotherModule.do_something() end def something_else do ... end end MyLib.SomeModule.something_else()

The reason this fails is because @on_load callbacks are invoked within the code server and therefore they have limited ability to load additional modules. It is generally advisable to limit invocation of external modules during @on_load callbacks but, in case it is strictly necessary, you can set @compile {:autoload, true} in the invoked module to address this issue in a forward and backwards compatible manner.

Parallel compilation of dependencies

This release introduces a variable called MIX_OS_DEPS_COMPILE_PARTITION_COUNT, which instructs mix deps.compile to compile dependencies in parallel.

While fetching dependencies and compiling individual Elixir dependencies already happened in parallel, there were pathological cases where performance would be left on the table, such as compiling dependencies with native code or dependencies where one or two large file would take over most of the compilation time.

By setting MIX_OS_DEPS_COMPILE_PARTITION_COUNT to a number greater than 1, Mix will now compile multiple dependencies at the same time, using separate OS processes. Empirical testing shows that setting it to half of the number of cores on your machine is enough to maximize resource usage. The exact speed up will depend on the number of dependencies and the number of machine cores, although some reports mention up to 4x faster compilation times. If you plan to enable it on CI or build servers, keep in mind it will most likely have a direct impact on memory usage too.

Improved pretty printing algorithm

Elixir v1.19 ships with a new pretty printing implementation that tracks limits as a whole, instead of per depth. Previous versions would track limits per depth. For example, if you had a list of lists of 4 elements and a limit of 5, it would be pretty printed as follows:

[ [1, 2, 3], [1, 2, ...], [1, ...], [...], ... ]

This allows for more information to be shown at different nesting levels, which is useful for complex data structures. But it led to some pathological cases where the limit option had little effect on actually filtering the amount of data shown. The new implementation decouples the limit handling from depth, decreasing it as it goes. Therefore, the list above with the same limit in Elixir v1.19 is now printed as:

[ [1, 2, 3], ... ]

The outer list is the first element, the first nested list is the second, followed by three numbers, reaching the limit. This gives developers more precise control over pretty printing.

Given this may reduce the amount of data printed by default, the default limit has also been increased from 50 to 100. We may further increase it in upcoming releases based on community feedback.

OpenChain certification

Elixir v1.19 is also our first release following OpenChain compliance, as previously announced. In a nutshell:

  • Elixir releases now include a Source SBoM in CycloneDX 1.6 or later and SPDX 2.3 or later formats.
  • Each release is attested along with the Source SBoM.

These additions offer greater transparency into the components and licenses of each release, supporting more rigorous supply chain requirements.

This work was performed by Jonatan Männchen and sponsored by the Erlang Ecosystem Foundation.

v1.19.0-rc.0 (2025-06-09)

1. Enhancements

Elixir

  • [Access] Add Access.values/0 for traversing maps and keyword lists values
  • [Base] Add functions to verify if an encoding is valid, such as valid16?, valid64?, and so forth
  • [Calendar] Support 2-arity options for Calendar.strftime/3 which receives the whole data type
  • [Code] Add :migrate_call_parens_on_pipe formatter option
  • [Code] Add :indentation option to Code.string_to_quoted/2
  • [Code.Fragment] Preserve more block content around cursor in container_cursor_to_quoted
  • [Code.Fragment] Add :block_keyword_or_binary_operator to Code.Fragment for more precise suggestions after operators and closing terminators
  • [Code.Fragment] Add Code.Fragment.lines/1
  • [Enum] Provide more information on Enum.OutOfBoundsError
  • [Inspect] Allow optional: :all when deriving Inspect
  • [Inspect.Algebra] Add optimistic/pessimistic groups as a simplified implementation of next_break_fits
  • [IO.ANSI] Add ANSI codes to turn off conceal and crossed_out
  • [Kernel] Allow controlling which applications are used during inference
  • [Kernel] Support min/2 and max/2 as guards
  • [Kernel.ParallelCompiler] Add each_long_verification_threshold which invokes a callback when type checking a module takes too long
  • [Kernel.ParallelCompiler] Include lines in == Compilation error in file ... == slogans
  • [Macro] Print debugging results from Macro.dbg/3 as they happen, instead of once at the end
  • [Module] Do not automatically load modules after their compilation, guaranteeing a more con...
Read more

v1.18.4

21 May 13:51
Compare
Choose a tag to compare

This release includes initial support for Erlang/OTP 28, for those who want to try it out. In such cases, you may use Elixir v1.18.4 precompiled for Erlang/OTP 27, as it is binary compatible with Erlang/OTP 28. Note, however, that Erlang/OTP 28 no longer allows regexes to be defined in the module body and interpolated into an attribute. If you do this:

@some_attribute ~r/foo/ def some_fun, do: @some_attribute

You must rewrite it to:

def some_fun, do: ~r/foo/

1. Enhancements

IEx

  • [IEx.Helpers] Add IEx.Helpers.process_info/1 which prints process information

Mix

  • [mix compile] Support the --no-listeners option
  • [mix local] Retry HTTP requests with disabled middlebox comp mode depending on the failure reason
  • [mix local.hex] Install Hex per OTP release
  • [mix local.rebar] Install Hex per OTP release
  • [mix run] Support the --no-listeners option

2. Bug fixes

Elixir

  • [Kernel] Emit trace events for @on_definition callbacks
  • [Kernel] Emit trace events for @on_load callbacks
  • [Kernel] Emit trace events for super calls
  • [Kernel] Emit trace events for imported function calls
  • [Kernel] Optimize map unions to avoid building long lists
  • [Kernel] Do not crash when type checking nested bitstrings in patterns
  • [Kernel] Do not crash when non-binary bitstring is given as struct default value
  • [Kernel] Recompile regexes when escaped from module attributes for Erlang/OTP 28 compatibility
  • [Kernel] Preserve backwards compatibility in elixir_erl

Mix

  • [mix deps.get] Ensure git checkout works when there are untracked files in the dependency
  • [mix loadpaths] Do not run listeners when not checking the deps

v1.18.3

06 Mar 10:11
Compare
Choose a tag to compare

1. Enhancements

Elixir

  • [JSON] Encode any JSON key to string
  • [Kernel] Allow <<_::3*8>> in typespecs

Mix

  • [mix loadpaths] Support --no-listeners option

2. Bug fixes

Elixir

  • [CLI] Fix --no-color not setting :ansi_enabled to false
  • [Protocol] Return correct implementation for an invalid struct pointing to nil
  • [Stream] Do not raise when Stream.cycle/1 is explicitly halted

ExUnit

  • [ExUnit.Diff] Fix regression when diffing nested improper lists

IEx

  • [IEx.Autocomplete] Fix autocomplete crash when expanding struct with __MODULE__
  • [IEx.Helpers] Do not purge on recompile if IEx is not running

v1.18.2

22 Jan 17:04
Compare
Choose a tag to compare

1. Enhancements

Elixir

  • [CLI] Add --color/--no-color for enabling and disabling of ANSI colors
  • [Code.Fragment] Provide more AST context when invoking container_cursor_to_quoted with trailing fragments
  • [Regex] Ensure compatibility with Erlang/OTP 28+ new Regex engine

Mix

  • [mix] Print compilation lock waiting message to stderr
  • [mix] Add an environment variable to optionally disable compilation locking

2. Bug fixes

Elixir

  • [CLI] Temporarily remove PowerShell scripts for elixir, elixirc, and mix on Windows, as they leave the shell broken after quitting Erlang

ExUnit

  • [ExUnit] Fix crash when diffing bitstring specifiers

IEx

  • [IEx.Autocomplete] Fix crashing whhen autocompleting structs with runtime values

Mix

  • [mix] Track compilation locks per user to avoid permission errors
  • [mix deps.update] Ensure Git dependencies can be upgraded by doing so against the origin

v1.18.1

24 Dec 09:26
Compare
Choose a tag to compare

1. Enhancements

  • [Kernel] Do not emit type violation warnings when comparing or matching against literals
  • [Kernel] Do not validate clauses of private overridable functions

2. Bug fixes

Elixir

  • [Code.Fragment] Ensure Code.Fragment.container_cursor_to_quoted/2 with :trailing_fragment parses expressions that were supported in previous versions
  • [Kernel] Do not crash when typing violation is detected on dynamic dispatch
  • [Kernel] Properly annotate the source for warnings emitted by the compiler with the @file annotation
  • [Kernel] Properly annotate the source for warnings emitted by the type system with the @file annotation
  • [Kernel] Remove :no_parens metadata when using capture with arity on all cases
  • [Kernel] Ensure diagnostic traces are kept backwards compatible

ExUnit

  • [ExUnit.Case] Ensure async groups do not run concurrenly while the test suite is still loading
  • [ExUnit.Case] Ensure --repeat-until-failure can be combined with groups

Mix

  • [mix compile.elixir] Store compilation results if compilation fails due to --warnings-as-errors
  • [mix deps.loadpaths] Add build lock
  • [mix escript.build] Ensure build succeeds when protocol consolidation is disabled
  • [Mix.Shell] Ensure encoding is properly respected on Windows and Unix systems