Compatibility and Deprecations

Compatibility between Elixir and Erlang/OTP

Erlang/OTP versioning is independent from the versioning of Elixir. Each version of Elixir supports a specific range of Erlang/OTP versions. The compatibility table is shown below.

Elixir versionSupported Erlang/OTP versions
1.017 - 17 (and OTP 18 from v1.0.5)
1.117 - 18
1.218 - 18 (and OTP 19 from v1.2.6)
1.318 - 19
1.418 - 19 (and OTP 20 from v1.4.5)
1.518 - 20
1.619 - 20 (and OTP 21 from v1.6.6)

While Elixir often adds compatibility to new Erlang versions on released branches, such as support for OTP 20 in v1.4.5, those releases usually contain the minimum changes for Elixir to run without errors. Only the next minor release, in this case v1.5.0, does effectively leverage the new features provided by the latest Erlang release.



Elixir deprecations happen in 3 steps:

  1. The feature is soft-deprecated. It means both CHANGELOG and documentation must list the feature as deprecated but no warning is effectively emitted by running the code. There is no requirement to soft-deprecate a feature.

  2. The feature is effectively deprecated by emitting warnings on usage. In order to deprecate a feature, the proposed alternative MUST exist for AT LEAST two versions. For example, Enum.uniq/2 was soft-deprecated in favor of Enum.uniq_by/2 in Elixir v1.1. This means a deprecation warning may only be emitted by Elixir v1.3 or later.

  3. The feature is removed. This can only happen on major releases. This means deprecated features in Elixir v1.x shall only be removed by Elixir v2.x.

Table of deprecations

Deprecated featureDeprecated inReplaced by (available since)
Enum.partition/2v1.6Enum.split_with/2 (v1.4)
Keyword.replace/3v1.6Use Keyword.fetch/2 + Keyword.put/3 (v1.0)
Macro.unescape_tokens/1 and Macro.unescape_tokens/2v1.6Use to traverse over the arguments (v1.0)
Module.add_doc/6v1.6Use @doc instead
Map.replace/3v1.6Use Map.fetch/2 + Map.put/3 (v1.0)
Range.range?/1v1.6Pattern match on _.._ instead (v1.0)
Atom.to_char_list/1v1.5Atom.to_charlist/1 (v1.3)
Enum.filter_map/3v1.5Enum.filter/2 + or for comprehensions (v1.0)
Float.to_char_list/1v1.5Float.to_charlist/1 (v1.3)
GenEvent modulev1.5Supervisor and GenServer (v1.0);
GenStage (v1.3);
:gen_event (OTP 17)
Integer.to_char_list/1 and Integer.to_char_list/2v1.5Integer.to_charlist/1 and Integer.to_charlist/2 (v1.3)
Kernel.to_char_list/1v1.5Kernel.to_charlist/1 (v1.3)
List.Chars.to_char_list/1v1.5List.Chars.to_charlist/1 (v1.3)
Stream.filter_map/3v1.5Stream.filter/2 + (v1.0)
String.ljust/3 and String.rjust/3v1.5String.pad_leading/3 and String.pad_trailing/3 with a binary padding (v1.3)
String.strip/1 and String.strip/2v1.5String.trim/1 and String.trim/2 (v1.3)
String.lstrip/1 and String.rstrip/1v1.5String.trim_leading/1 and String.trim_trailing/1 (v1.3)
String.lstrip/2 and String.rstrip/2v1.5String.trim_leading/2 and String.trim_trailing/2 with a binary as second argument (v1.3)
String.to_char_list/1v1.5String.to_charlist/1 (v1.3)
() to mean nilv1.5nil (v1.0)
:as_char_lists value in Inspect.Opts.t/0 typev1.5:as_charlists (v1.3)
:char_lists key in Inspect.Opts.t/0 typev1.5:charlists (v1.3)
char_list/0 typev1.5charlist/0 type (v1.3)
@compile {:parse_transform, _} in Modulev1.5None
EEx: <%= in middle and end expressionsv1.5Use <% (= is allowed only on start expressions) (v1.0)
Access.key/1v1.4Access.key/2 (v1.3)
Behaviour modulev1.4@callback (v1.0)
Enum.uniq/2v1.4Enum.uniq_by/2 (v1.2)
Float.to_char_list/2v1.4:erlang.float_to_list/2 (OTP 17)
Float.to_string/2v1.4:erlang.float_to_binary/2 (OTP 17)
HashDict modulev1.4Map (v1.2)
HashSet modulev1.4MapSet (v1.1)
Multi-letter aliases in OptionParserv1.4Use single-letter aliases (v1.0)
Set modulev1.4MapSet (v1.1)
Stream.uniq/2v1.4Stream.uniq_by/2 (v1.2)
IEx.Helpers.import_file/2v1.4IEx.Helpers.import_file_if_available/1 (v1.3)
Mix.Utils.camelize/1v1.4Macro.camelize/1 (v1.2)
Mix.Utils.underscore/1v1.4Macro.underscore/1 (v1.2)
Variable used as function callv1.4Use parentheses (v1.0)
Anonymous functions with no expression after ->v1.4Use an expression or explicitly return nil (v1.0)
Support for making private functions overridablev1.4Use public functions (v1.0)
Dict modulev1.3Keyword (v1.0) or Map (v1.2)
Keyword.size/1v1.3Kernel.length/1 (v1.0)
Map.size/1v1.3Kernel.map_size/1 (v1.0)
Set behaviourv1.3MapSet data structure (v1.1)
String.valid_character?/1v1.3String.valid?/1 (v1.0)
Task.find/2v1.3Use direct message matching (v1.0)
:append_first option in Kernel.defdelegate/2v1.3Define the function explicitly (v1.0)
/r option in Regexv1.3/U (v1.1)
\x{X*} inside strings/sigils/charlistsv1.3\uXXXX or \u{X*} (v1.1)
Map or dictionary as second argument in Enum.group_by/3v1.3Use Enum.reduce/3 (v1.0)
Non-map as second argument in URI.decode_query/2v1.3Use a map (v1.0)
Dict behaviourv1.2MapSet data structure (v1.1)
Access protocolv1.1Access behaviour (v1.1)
as: true | false in alias/2 and require/2v1.1None
?\xHEXv1.10xHEX (v1.0)