<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://www.erlang.org/news.xml" rel="self" type="application/atom+xml" /><link href="https://www.erlang.org/" rel="alternate" type="text/html" /><updated>2026-07-14T02:02:15+00:00</updated><id>https://www.erlang.org/news.xml</id><title type="html">Erlang/OTP | News</title><subtitle>The official home of the Erlang Programming Language</subtitle><entry><title type="html">Björn on BEAM on the BEAM There, Done That Podcast</title><link href="https://www.erlang.org/news/190" rel="alternate" type="text/html" title="Björn on BEAM on the BEAM There, Done That Podcast" /><published>2026-06-26T00:00:00+00:00</published><updated>2026-06-26T00:00:00+00:00</updated><id>https://www.erlang.org/news/190</id><content type="html" xml:base="https://www.erlang.org/news/190"><![CDATA[<h1 id="björn-gustavsson-on-beam-on-the-beam-there-done-that-podcast">Björn Gustavsson on BEAM on the “BEAM There, Done That” Podcast</h1>

<p>The YouTube channel <a href="https://www.youtube.com/@BEAMThereDoneThat">BEAM There, Done That</a>
has new video about the origin of the BEAM:</p>

<p><a href="https://youtu.be/1Ty_MHZu9nM?si=L99dI6FvwNJi46S2">30 Years Inside the BEAM: Björn Gustavsson on Building Erlang’s Runtime</a></p>]]></content><author><name>Björn Gustavsson</name></author><category term="blog," /><category term="youtube" /><summary type="html"><![CDATA[Björn Gustavsson on BEAM on the “BEAM There, Done That” Podcast]]></summary></entry><entry><title type="html">Native Records on the Podcast BEAM There, Done That</title><link href="https://www.erlang.org/news/189" rel="alternate" type="text/html" title="Native Records on the Podcast BEAM There, Done That" /><published>2026-05-28T00:00:00+00:00</published><updated>2026-05-28T00:00:00+00:00</updated><id>https://www.erlang.org/news/189</id><content type="html" xml:base="https://www.erlang.org/news/189"><![CDATA[<h1 id="more-about-native-records-on-the-beam-there-done-that-podcast">More About Native Records on the “BEAM There, Done That” Podcast</h1>

<p>The YouTube channel <a href="https://www.youtube.com/@BEAMThereDoneThat">BEAM There, Done That</a>
has new video about native records and more:</p>

<p><a href="https://youtu.be/0zpJpHtPuGE">Inside the BEAM: Björn Gustavsson on Maps, Records, and Runtime Design</a>.</p>]]></content><author><name>Björn Gustavsson</name></author><category term="blog," /><category term="youtube" /><summary type="html"><![CDATA[More About Native Records on the “BEAM There, Done That” Podcast]]></summary></entry><entry><title type="html">Erlang/OTP 29.0</title><link href="https://www.erlang.org/news/188" rel="alternate" type="text/html" title="Erlang/OTP 29.0" /><published>2026-05-13T00:00:00+00:00</published><updated>2026-05-13T00:00:00+00:00</updated><id>https://www.erlang.org/news/188</id><content type="html" xml:base="https://www.erlang.org/news/188"><![CDATA[<h2 id="otp-290">OTP 29.0</h2>

<p>Erlang/OTP 29 is a new major release with new features, improvements
as well as a few incompatibilities. Some of the new features are
highlighted below.</p>

<p>Many thanks to all contributors!</p>

<h1 id="highlights">Highlights</h1>

<ul>
  <li>
    <p>Added support for <code>-unsafe</code> attributes for marking
functions as unsafe to use. The compiler will by default now
generate warnings for calls to functions in Erlang/OTP known to be
always unsafe. Furthermore, <code>xref</code> can now be used to find calls to
unsafe functions and functions that lack documentation.</p>
  </li>
  <li>
    <p>The SSH daemon now defaults to disabled for shell and exec services,
implementing the “secure by default” principle. This prevents
authenticated users from executing arbitrary Erlang code unless
explicitly configured.</p>
  </li>
  <li>
    <p>The SFTP subsystem is no longer enabled by default when starting an
SSH daemon.</p>
  </li>
  <li>
    <p>In SSL, the post quantum hybrid algorithm x25519mlkem768 is now the
most preferred key exchange group in the default configuration.</p>
  </li>
  <li>
    <p>The module <code>io_ansi</code> allows the user to emit Virtual Terminal
Sequences (also known as ANSI sequences) to the terminal in order to
add colors/styling to text or to create fully fledged terminal
applications.</p>
  </li>
  <li>
    <p>The new <code>ct_doctest</code> module allows the user to test
documentation examples in Erlang module docs and documentation files.</p>
  </li>
  <li>
    <p>The <code>ignore_xref</code> attribute has been handled as a post-analysis
filter by build tools such as Rebar3. In this release, [<code>xref</code>]
itself does the filtering, ensuring that all tooling that calls
<code>xref</code> for any purpose can rely on these declarations to just work.</p>
  </li>
</ul>

<h2 id="general">General</h2>

<ul>
  <li>
    <p>In the default code path for the Erlang system, the current working
directory (<code>.</code>) is now in the last position instead of the first.</p>
  </li>
  <li>
    <p>There is no longer a 32-bit Erlang/OTP build for Windows.</p>
  </li>
</ul>

<h2 id="new-language-features">New language features</h2>

<ul>
  <li>
    <p>Native records as described in
<a href="https://github.com/erlang/eep/pull/81">EEP-79</a> has been
implemented. A native record is a data structure similar to the
traditional tuple-based records, except that is a true data type.
Native records are considered experimental in Erlang/OTP 29 and
possibly also in Erlang/OTP 30.</p>
  </li>
  <li>
    <p>The new <code>is_integer/3</code> guard BIF makes it possible to easily verify
that a value is both an integer and within a certain range. For
example: <code>is_integer(I, 0, 100)</code></p>
  </li>
  <li>
    <p>Multi-valued comprehensions according to <a href="https://www.erlang.org/eeps/eep-0078">EEP 78</a>
are now supported. For example, <code>[-I, I || I &lt;- [1, 2, 3]]</code> will produce
<code>[-1,1,-2,2,-3,3]</code>.</p>
  </li>
  <li>
    <p>By enabling the <code>compr_assign</code> feature, it is now possible to bind variables
in a comprehensions. For example:
<code>[H || E &lt;- List, H = erlang:phash2(E), H rem 10 =:= 0]</code></p>
  </li>
</ul>

<h2 id="compiler-and-jit-improvements">Compiler and JIT improvements</h2>

<ul>
  <li>
    <p>In the documentation for the [<code>compile</code>] module, there is now a section
with recommendations for implementors of languages running on
the BEAM.</p>
  </li>
  <li>
    <p>The JIT now generates better code for matching or creating binaries with
multiple little-endian segments.</p>
  </li>
  <li>
    <p>The compiler will generate more efficient code for map
comprehensions with constant values that don’t depend on the
generator. Example: <code>#{K =&gt; 42 || K &lt;- List}</code></p>
  </li>
</ul>

<h2 id="compiler-warnings">Compiler warnings</h2>

<p>There are several new compiler warnings enabled by default. For each
such warning, there is an option to disable it.</p>

<ul>
  <li>
    <p>There will now be a warning when using the <code>catch</code> operator, which
has been deprecated for a long time.  It is recommended to instead
use <code>try</code>…<code>catch</code> but is also possible to disable the warning
by using the <code>nowarn_deprecated_catch</code> option.</p>
  </li>
  <li>
    <p>There will now be a warning when exporting variables out of a
subexpression.  For example: <code>file:open(File, AllOpts = [write,
{encoding,utf8}])</code>. This warning can be disabled using the
<code>nowarn_export_var_subexpr</code> compiler option.</p>
  </li>
  <li>
    <p>The compiler will now warn for uses of the <code>and</code> and <code>or</code>
operators. This warning can be disabled using the
<code>nowarn_obsolete_bool_op</code> compiler option.</p>
  </li>
  <li>
    <p>The compiler will now warn for matches such as <code>{a,B} = {X,Y}</code>,
which is better written as <code>{a=X,B=Y}</code>. This warning can be disabled
using the <code>nowarn_match_alias_pats</code> option.</p>
  </li>
</ul>

<p>For a long time, there has been a warning for using the obsolete guard
tests (such as <code>list(L)</code> instead of <code>is_list(L)</code>. In Erlang/OTP 30, the
old guards will be removed from the language.</p>

<h2 id="stdlib">STDLIB</h2>

<ul>
  <li>There are new functions for randomly permutating a list: <code>rand:shuffle/1</code> and
<code>rand:shuffle_s/2</code>.</li>
</ul>

<h2 id="ssh">SSH</h2>

<ul>
  <li>The default key exchange algorithm is now mlkem768x25519-sha256, a hybrid
quantum-resistant algorithm combining ML-KEM-768 with X25519. This provides
protection against both classical and quantum computer attacks while
maintaining backward compatibility through automatic fallback to other
algorithms when peers don’t support it.</li>
</ul>

<p>For a full list and more details about new features and potential incompatibilities see the <a href="https://erlang.org/download/otp_src_29.0.readme">README</a>.</p>]]></content><author><name>Henrik Nord</name></author><category term="release," /><category term="OTP," /><category term="29.0," /><category term="Release" /><summary type="html"><![CDATA[OTP 29.0]]></summary></entry><entry><title type="html">Erlang/OTP 28.5 Release</title><link href="https://www.erlang.org/news/187" rel="alternate" type="text/html" title="Erlang/OTP 28.5 Release" /><published>2026-04-23T00:00:00+00:00</published><updated>2026-04-23T00:00:00+00:00</updated><id>https://www.erlang.org/news/187</id><content type="html" xml:base="https://www.erlang.org/news/187"><![CDATA[<h2 id="otp-285">OTP 28.5</h2>

<p>Erlang/OTP 28.5 is the fourth maintenance patch package for OTP 28, with mostly bug fixes as well as a few improvements.</p>

<h1 id="highlights">HIGHLIGHTS</h1>
<p>There is a new “Secure Coding Guidelines” document in Design Principles describing how to write secure Erlang code.</p>

<h2 id="improvements-and-new-features">Improvements and New Features</h2>

<ul>
  <li>
    <p>A new <code>configure</code> option <code>--{enable,disable}-use-embedded-3pp-alternatives</code> has been added. When <em>enabled</em>, <code>configure</code> is forced to find alternatives,
 to a subset, of the embedded third-party products (<em>3pps</em>) in the runtime system, and when <em>disabled</em>, <code>configure</code> will use all internal embedded 3pps.
Currently this option affects <code>zstd</code>, <code>zlib</code>, <code>ryu</code> (with <code>STL</code>), <code>openssl</code> and <code>tcl</code>. The default is to use all built-in embedded 3pps except for <code>zlib</code>
which by default will use <code>zlib</code> on the OS if available.</p>

    <p>Requirements for alternatives:</p>

    <ul>
      <li><code>zstd</code> - Static library and include files of at least version 1.5.6 needs to be available.</li>
      <li><code>zlib</code> - Library and include files of at least version 1.2.5 needs to be available.</li>
      <li><code>ryu</code> (with <code>STL</code>) - A usable C++ compiler with C++17 support.</li>
      <li><code>openssl</code> - No requirements. Our own MD5 implementation will be used.</li>
      <li><code>tcl</code> - The <code>strerrorname_np()</code> function (introduced in glibc 2.32) mapping errno integers to symbolic names needs to be available.</li>
    </ul>

    <p>The argument <code>embedded_3pps</code> has been added to erlang:system_info/1. It returns a map with information about the use of embedded 3pps in the runtime
system.</p>
  </li>
</ul>

<p>For details about bugfixes and potential incompatibilities see the <a href="https://erlang.org/download/OTP-28.5.README">Erlang 28.5 README</a></p>

<p>The Erlang/OTP source can also be found at GitHub on the official Erlang repository, https://github.com/erlang/otp</p>

<p>Download links for this and previous versions are found here:</p>

<ul>
  <li><a href="/downloads">https://www.erlang.org/downloads</a></li>
</ul>]]></content><author><name>Henrik Nord</name></author><category term="release," /><category term="OTP," /><category term="28.5" /><summary type="html"><![CDATA[OTP 28.5]]></summary></entry><entry><title type="html">Erlang/OTP 29.0 Release Candidate 3</title><link href="https://www.erlang.org/news/186" rel="alternate" type="text/html" title="Erlang/OTP 29.0 Release Candidate 3" /><published>2026-04-15T00:00:00+00:00</published><updated>2026-04-15T00:00:00+00:00</updated><id>https://www.erlang.org/news/186</id><content type="html" xml:base="https://www.erlang.org/news/186"><![CDATA[<h2 id="otp-290-rc3">OTP 29.0-rc3</h2>

<p>Erlang/OTP 29.0-rc3 is the third and final release candidate before
the OTP 29.0 release.</p>

<p>The intention with this release is to get feedback from our users.
All feedback is welcome, even if it is only to say that it works for you.
We encourage users to try it out and give us feedback either by creating an issue at
<a href="https://github.com/erlang/otp/issues">https://github.com/erlang/otp/issues</a> or by
posting to <a href="https://erlangforums.com/">Erlang Forums</a>.</p>

<p>All artifacts for the release can be downloaded from the
<a href="https://github.com/erlang/otp/releases/tag/OTP-29.0-rc3">Erlang/OTP Github</a> release
and you can view the new documentation at
<a href="https://erlang.org/documentation/doc-17.0-rc3/doc/">https://erlang.org/documentation/doc-17.0-rc3/doc</a>.
You can also install the latest release using <a href="https://github.com/kerl/kerl">kerl</a> like this:</p>

<pre><code>kerl build 29.0-rc3 29.0-rc3.
</code></pre>

<p>Erlang/OTP 29 is a new major release with new features, improvements
as well as a few incompatibilities. Some of the new features are
highlighted below.</p>

<p>Many thanks to all contributors!</p>

<h1 id="highlights-for-rc3">Highlights for RC3</h1>

<ul>
  <li>
    <p>Added support for <code>-unsafe</code> attributes for marking
functions as unsafe to use. The compiler will by default now
generate warnings for calls to functions in Erlang/OTP known to be
always unsafe. Furthermore, <code>xref</code> can now be used to find calls to
unsafe functions and functions that lack documentation.</p>
  </li>
  <li>
    <p>The SSH daemon now defaults to disabled for shell and exec services,
implementing the “secure by default” principle. This prevents
authenticated users from executing arbitrary Erlang code unless
explicitly configured.</p>
  </li>
  <li>
    <p>The SFTP subsystem is no longer enabled by default when starting an
SSH daemon.</p>
  </li>
  <li>
    <p>In SSL, the post quantum hybrid algorithm x25519mlkem768 is now the
most preferred key exchange group in the default configuration.</p>
  </li>
</ul>

<h1 id="highlights-for-rc2">Highlights for RC2</h1>

<ul>
  <li>
    <p>The module <code>io_ansi</code> allows the user to emit Virtual Terminal
Sequences (also known as ANSI sequences) to the terminal in order to
add colors/styling to text or to create fully fledged terminal
applications.</p>
  </li>
  <li>
    <p>The new <code>ct_doctest</code> module allows the user to test
documentation examples in Erlang module docs and documentation files.</p>
  </li>
  <li>
    <p>The <code>ignore_xref</code> attribute has been handled as a post-analysis
filter by build tools such as Rebar3. In this release, [<code>xref</code>]
itself does the filtering, ensuring that all tooling that calls
<code>xref</code> for any purpose can rely on these declarations to just work.</p>
  </li>
</ul>

<h1 id="highlights-for-rc1">Highlights for RC1</h1>

<h2 id="general">General</h2>

<ul>
  <li>
    <p>In the default code path for the Erlang system, the current working
directory (<code>.</code>) is now in the last position instead of the first.</p>
  </li>
  <li>
    <p>There is no longer a 32-bit Erlang/OTP build for Windows.</p>
  </li>
</ul>

<h2 id="new-language-features">New language features</h2>

<ul>
  <li>
    <p>Native records as described in
<a href="https://github.com/erlang/eep/pull/81">EEP-79</a> has been
implemented. A native record is a data structure similar to the
traditional tuple-based records, except that is a true data type.
Native records are considered experimental in Erlang/OTP 29 and
possibly also in Erlang/OTP 30.</p>
  </li>
  <li>
    <p>The new <code>is_integer/3</code> guard BIF makes it possible to easily verify
that a value is both an integer and within a certain range. For
example: <code>is_integer(I, 0, 100)</code></p>
  </li>
  <li>
    <p>Multi-valued comprehensions according to <a href="https://www.erlang.org/eeps/eep-0078">EEP 78</a>
are now supported. For example, <code>[-I, I || I &lt;- [1, 2, 3]]</code> will produce
<code>[-1,1,-2,2,-3,3]</code>.</p>
  </li>
  <li>
    <p>By enabling the <code>compr_assign</code> feature, it is now possible to bind variables
in a comprehensions. For example:
<code>[H || E &lt;- List, H = erlang:phash2(E), H rem 10 =:= 0]</code></p>
  </li>
</ul>

<h2 id="compiler-and-jit-improvements">Compiler and JIT improvements</h2>

<ul>
  <li>
    <p>In the documentation for the [<code>compile</code>] module, there is now a section
with recommendations for implementors of languages running on
the BEAM.</p>
  </li>
  <li>
    <p>The JIT now generates better code for matching or creating binaries with
multiple little-endian segments.</p>
  </li>
  <li>
    <p>The compiler will generate more efficient code for map
comprehensions with constant values that don’t depend on the
generator. Example: <code>#{K =&gt; 42 || K &lt;- List}</code></p>
  </li>
</ul>

<h2 id="compiler-warnings">Compiler warnings</h2>

<p>There are several new compiler warnings enabled by default. For each
such warning, there is an option to disable it.</p>

<ul>
  <li>
    <p>There will now be a warning when using the <code>catch</code> operator, which
has been deprecated for a long time.  It is recommended to instead
use <code>try</code>…<code>catch</code> but is also possible to disable the warning
by using the <code>nowarn_deprecated_catch</code> option.</p>
  </li>
  <li>
    <p>There will now be a warning when exporting variables out of a
subexpression.  For example: <code>file:open(File, AllOpts = [write,
{encoding,utf8}])</code>. This warning can be disabled using the
<code>nowarn_export_var_subexpr</code> compiler option.</p>
  </li>
  <li>
    <p>The compiler will now warn for uses of the <code>and</code> and <code>or</code>
operators. This warning can be disabled using the
<code>nowarn_obsolete_bool_op</code> compiler option.</p>
  </li>
  <li>
    <p>The compiler will now warn for matches such as <code>{a,B} = {X,Y}</code>,
which is better written as <code>{a=X,B=Y}</code>. This warning can be disabled
using the <code>nowarn_match_alias_pats</code> option.</p>
  </li>
</ul>

<p>For a long time, there has been a warning for using the obsolete guard
tests (such as <code>list(L)</code> instead of <code>is_list(L)</code>. In Erlang/OTP 30, the
old guards will be removed from the language.</p>

<h2 id="stdlib">STDLIB</h2>

<ul>
  <li>There are new functions for randomly permutating a list: <code>rand:shuffle/1</code> and
<code>rand:shuffle_s/2</code>.</li>
</ul>

<h2 id="ssh">SSH</h2>

<ul>
  <li>The default key exchange algorithm is now mlkem768x25519-sha256, a hybrid
quantum-resistant algorithm combining ML-KEM-768 with X25519. This provides
protection against both classical and quantum computer attacks while
maintaining backward compatibility through automatic fallback to other
algorithms when peers don’t support it.</li>
</ul>

<p>For more details about new features and potential incompatibilities see the <a href="https://erlang.org/download/otp_src_29.0-rc3.readme">README</a>.</p>]]></content><author><name>Björn Gustavsson</name></author><category term="release," /><category term="OTP," /><category term="29.0-rc3," /><category term="Release" /><category term="Candidate" /><summary type="html"><![CDATA[OTP 29.0-rc3]]></summary></entry><entry><title type="html">Erlang/OTP 29.0 Release Candidate 2</title><link href="https://www.erlang.org/news/185" rel="alternate" type="text/html" title="Erlang/OTP 29.0 Release Candidate 2" /><published>2026-03-18T00:00:00+00:00</published><updated>2026-03-18T00:00:00+00:00</updated><id>https://www.erlang.org/news/185</id><content type="html" xml:base="https://www.erlang.org/news/185"><![CDATA[<h2 id="otp-290-rc2">OTP 29.0-rc2</h2>

<p>Erlang/OTP 29.0-rc2 is the second release candidate of three before the OTP 29.0 release.</p>

<p>The intention with this release is to get feedback from our users.
All feedback is welcome, even if it is only to say that it works for you.
We encourage users to try it out and give us feedback either by creating an issue at
<a href="https://github.com/erlang/otp/issues">https://github.com/erlang/otp/issues</a> or by
posting to <a href="https://erlangforums.com/">Erlang Forums</a>.</p>

<p>All artifacts for the release can be downloaded from the
<a href="https://github.com/erlang/otp/releases/tag/OTP-29.0-rc2">Erlang/OTP Github</a> release
and you can view the new documentation at
<a href="https://erlang.org/documentation/doc-17.0-rc2/doc/">https://erlang.org/documentation/doc-17.0-rc2/doc</a>.
You can also install the latest release using <a href="https://github.com/kerl/kerl">kerl</a> like this:</p>

<pre><code>kerl build 29.0-rc2 29.0-rc2.
</code></pre>

<p>Erlang/OTP 29 is a new major release with new features, improvements
as well as a few incompatibilities. Some of the new features are
highlighted below.</p>

<p>Many thanks to all contributors!</p>

<h1 id="highlights-for-rc2">Highlights for RC2</h1>

<ul>
  <li>
    <p>The module <code>io_ansi</code> allows the user to emit Virtual Terminal
Sequences (also known as ANSI sequences) to the terminal in order to
add colors/styling to text or to create fully fledged terminal
applications.</p>
  </li>
  <li>
    <p>The new <code>ct_doctest</code> module allows the user to test
documentation examples in Erlang module docs and documentation files.</p>
  </li>
  <li>
    <p>The <code>ignore_xref</code> attribute has been handled as a post-analysis
filter by build tools such as Rebar3. In this release, [<code>xref</code>]
itself does the filtering, ensuring that all tooling that calls
<code>xref</code> for any purpose can rely on these declarations to just work.</p>
  </li>
</ul>

<h1 id="highlights-for-rc1">Highlights for RC1</h1>

<h2 id="general">General</h2>

<ul>
  <li>
    <p>In the default code path for the Erlang system, the current working
directory (<code>.</code>) is now in the last position instead of the first.</p>
  </li>
  <li>
    <p>There is no longer a 32-bit Erlang/OTP build for Windows.</p>
  </li>
</ul>

<h2 id="new-language-features">New language features</h2>

<ul>
  <li>
    <p>Native records as described in
<a href="https://github.com/erlang/eep/pull/81">EEP-79</a> has been
implemented. A native record is a data structure similar to the
traditional tuple-based records, except that is a true data type.
Native records are considered experimental in Erlang/OTP 29 and
possibly also in Erlang/OTP 30.</p>
  </li>
  <li>
    <p>The new <code>is_integer/3</code> guard BIF makes it possible to easily verify
that a value is both an integer and within a certain range. For
example: <code>is_integer(I, 0, 100)</code></p>
  </li>
  <li>
    <p>Multi-valued comprehensions according to <a href="https://www.erlang.org/eeps/eep-0078">EEP 78</a>
are now supported. For example, <code>[-I, I || I &lt;- [1, 2, 3]]</code> will produce
<code>[-1,1,-2,2,-3,3]</code>.</p>
  </li>
  <li>
    <p>By enabling the <code>compr_assign</code> feature, it is now possible to bind variables
in a comprehensions. For example:
<code>[H || E &lt;- List, H = erlang:phash2(E), H rem 10 =:= 0]</code></p>
  </li>
</ul>

<h2 id="compiler-and-jit-improvements">Compiler and JIT improvements</h2>

<ul>
  <li>
    <p>In the documentation for the [<code>compile</code>] module, there is now a section
with recommendations for implementors of languages running on
the BEAM.</p>
  </li>
  <li>
    <p>The JIT now generates better code for matching or creating binaries with
multiple little-endian segments.</p>
  </li>
  <li>
    <p>The compiler will generate more efficient code for map
comprehensions with constant values that don’t depend on the
generator. Example: <code>#{K =&gt; 42 || K &lt;- List}</code></p>
  </li>
</ul>

<h2 id="compiler-warnings">Compiler warnings</h2>

<p>There are several new compiler warnings enabled by default. For each
such warning, there is an option to disable it.</p>

<ul>
  <li>
    <p>There will now be a warning when using the <code>catch</code> operator, which
has been deprecated for a long time.  It is recommended to instead
use <code>try</code>…<code>catch</code> but is also possible to disable the warning
by using the <code>nowarn_deprecated_catch</code> option.</p>
  </li>
  <li>
    <p>There will now be a warning when exporting variables out of a
subexpression.  For example: <code>file:open(File, AllOpts = [write,
{encoding,utf8}])</code>. This warning can be disabled using the
<code>nowarn_export_var_subexpr</code> compiler option.</p>
  </li>
  <li>
    <p>The compiler will now warn for uses of the <code>and</code> and <code>or</code>
operators. This warning can be disabled using the
<code>nowarn_obsolete_bool_op</code> compiler option.</p>
  </li>
  <li>
    <p>The compiler will now warn for matches such as <code>{a,B} = {X,Y}</code>,
which is better written as <code>{a=X,B=Y}</code>. This warning can be disabled
using the <code>nowarn_match_alias_pats</code> option.</p>
  </li>
</ul>

<p>For a long time, there has been a warning for using the obsolete guard
tests (such as <code>list(L)</code> instead of <code>is_list(L)</code>. In Erlang/OTP 30, the
old guards will be removed from the language.</p>

<h2 id="stdlib">STDLIB</h2>

<ul>
  <li>There are new functions for randomly permutating a list: <code>rand:shuffle/1</code> and
<code>rand:shuffle_s/2</code>.</li>
</ul>

<h2 id="ssh">SSH</h2>

<ul>
  <li>The default key exchange algorithm is now mlkem768x25519-sha256, a hybrid
quantum-resistant algorithm combining ML-KEM-768 with X25519. This provides
protection against both classical and quantum computer attacks while
maintaining backward compatibility through automatic fallback to other
algorithms when peers don’t support it.</li>
</ul>

<p>For more details about new features and potential incompatibilities see the <a href="https://erlang.org/download/otp_src_29.0-rc2.readme">README</a>.</p>]]></content><author><name>Björn Gustavsson</name></author><category term="release," /><category term="OTP," /><category term="29.0-rc2," /><category term="Release" /><category term="Candidate" /><summary type="html"><![CDATA[OTP 29.0-rc2]]></summary></entry><entry><title type="html">Erlang/OTP 28.4 Release</title><link href="https://www.erlang.org/news/184" rel="alternate" type="text/html" title="Erlang/OTP 28.4 Release" /><published>2026-03-04T00:00:00+00:00</published><updated>2026-03-04T00:00:00+00:00</updated><id>https://www.erlang.org/news/184</id><content type="html" xml:base="https://www.erlang.org/news/184"><![CDATA[<h2 id="otp-284">OTP 28.4</h2>

<p>Erlang/OTP 28.4 is the third maintenance patch package for OTP 28, with mostly bug fixes as well as improvements.</p>

<h1 id="highlights">HIGHLIGHTS</h1>
<h2 id="ssh">ssh</h2>
<ul>
  <li>Added support for the PQC key exchange (kex) algorithm mlkem768x25519-sha256,
a hybrid quantum-resistant algorithm combining ML-KEM-768 with X25519.
    <h2 id="erts">erts</h2>
  </li>
  <li>Added persistent_term:put_new/2 that will quickly do nothing if a term with
the given name and value already exists, and raise a <code>badarg</code> exception if the
term exists with a different value.</li>
</ul>

<h1 id="potential-incompatibilities">POTENTIAL INCOMPATIBILITIES</h1>

<ul>
  <li>Added a new HttpOption <code>{autoretry, timeout()}</code> to <code>httpc:request/4,5</code>. This
option allows the client to decide how to act upon receiving a Retry-After
response header. The default behavior changes, as now only one retry is made
before returning the error code, instead of retrying infinitely.</li>
</ul>

<p>For details about bugfixes and potential incompatibilities see
the <a href="https://erlang.org/download/OTP-28.4.README">Erlang 28.4 README</a></p>

<p>The Erlang/OTP source can also be found at GitHub on the official Erlang repository,
https://github.com/erlang/otp</p>

<p>Download links for this and previous versions are found here:</p>

<ul>
  <li><a href="/downloads">https://www.erlang.org/downloads</a></li>
</ul>]]></content><author><name>Henrik Nord</name></author><category term="release," /><category term="OTP," /><category term="28.4" /><summary type="html"><![CDATA[OTP 28.4]]></summary></entry><entry><title type="html">Erlang/OTP 29.0 Release Candidate 1</title><link href="https://www.erlang.org/news/183" rel="alternate" type="text/html" title="Erlang/OTP 29.0 Release Candidate 1" /><published>2026-02-11T00:00:00+00:00</published><updated>2026-02-11T00:00:00+00:00</updated><id>https://www.erlang.org/news/183</id><content type="html" xml:base="https://www.erlang.org/news/183"><![CDATA[<h2 id="otp-290-rc1">OTP 29.0-rc1</h2>

<p>Erlang/OTP 29.0-rc1 is the first release candidate of three before the OTP 29.0 release.</p>

<p>The intention with this release is to get feedback from our users.
All feedback is welcome, even if it is only to say that it works for you.
We encourage users to try it out and give us feedback either by creating an issue at
<a href="https://github.com/erlang/otp/issues">https://github.com/erlang/otp/issues</a> or by
posting to <a href="https://erlangforums.com/">Erlang Forums</a>.</p>

<p>All artifacts for the release can be downloaded from the
<a href="https://github.com/erlang/otp/releases/tag/OTP-29.0-rc1">Erlang/OTP Github</a> release
and you can view the new documentation at
<a href="https://erlang.org/documentation/doc-17.0-rc1/doc/">https://erlang.org/documentation/doc-17.0-rc1/doc</a>.
You can also install the latest release using <a href="https://github.com/kerl/kerl">kerl</a> like this:</p>

<pre><code>kerl build 29.0-rc1 29.0-rc1.
</code></pre>

<p>Erlang/OTP 29 is a new major release with new features, improvements
as well as a few incompatibilities. Some of the new features are
highlighted below.</p>

<p>Many thanks to all contributors!</p>

<h2 id="general">General</h2>

<ul>
  <li>
    <p>In the default code path for the Erlang system, the current working
directory (<code>.</code>) is now in the last position instead of the first.</p>
  </li>
  <li>
    <p>There is no longer a 32-bit Erlang/OTP build for Windows.</p>
  </li>
</ul>

<h2 id="new-language-features">New language features</h2>

<ul>
  <li>
    <p>Native records as described in
<a href="https://github.com/erlang/eep/pull/81">EEP-79</a> has been
implemented. A native record is a data structure similar to the
traditional tuple-based records, except that is a true data type.
Native records are considered experimental in Erlang/OTP 29 and
possibly also in Erlang/OTP 30.</p>
  </li>
  <li>
    <p>The new <code>is_integer/3</code> guard BIF makes it possible to easily verify
that a value is both an integer and within a certain range. For
example: <code>is_integer(I, 0, 100)</code></p>
  </li>
  <li>
    <p>Multi-valued comprehensions according to <a href="https://www.erlang.org/eeps/eep-0078">EEP 78</a>
are now supported. For example, <code>[-I, I || I &lt;- [1, 2, 3]]</code> will produce
<code>[-1,1,-2,2,-3,3]</code>.</p>
  </li>
  <li>
    <p>By enabling the <code>compr_assign</code> feature, it is now possible to bind variables
in a comprehensions. For example:
<code>[H || E &lt;- List, H = erlang:phash2(E), H rem 10 =:= 0]</code></p>
  </li>
</ul>

<h2 id="compiler-and-jit-improvements">Compiler and JIT improvements</h2>

<ul>
  <li>
    <p>In the documentation for the [<code>compile</code>] module, there is now a section
with recommendations for implementors of languages running on
the BEAM.</p>
  </li>
  <li>
    <p>The JIT now generates better code for matching or creating binaries with
multiple little-endian segments.</p>
  </li>
  <li>
    <p>The compiler will generate more efficient code for map
comprehensions with constant values that don’t depend on the
generator. Example: <code>#{K =&gt; 42 || K &lt;- List}</code></p>
  </li>
</ul>

<h2 id="compiler-warnings">Compiler warnings</h2>

<p>There are several new compiler warnings enabled by default. For each
such warning, there is an option to disable it.</p>

<ul>
  <li>
    <p>There will now be a warning when using the <code>catch</code> operator, which
has been deprecated for a long time.  It is recommended to instead
use <code>try</code>…<code>catch</code> but is also possible to disable the warning
by using the <code>nowarn_deprecated_catch</code> option.</p>
  </li>
  <li>
    <p>There will now be a warning when exporting variables out of a
subexpression.  For example: <code>file:open(File, AllOpts = [write,
{encoding,utf8}])</code>. This warning can be disabled using the
<code>nowarn_export_var_subexpr</code> compiler option.</p>
  </li>
  <li>
    <p>The compiler will now warn for uses of the <code>and</code> and <code>or</code>
operators. This warning can be disabled using the
<code>nowarn_obsolete_bool_op</code> compiler option.</p>
  </li>
  <li>
    <p>The compiler will now warn for matches such as <code>{a,B} = {X,Y}</code>,
which is better written as <code>{a=X,B=Y}</code>. This warning can be disabled
using the <code>nowarn_match_alias_pats</code> option.</p>
  </li>
</ul>

<p>For a long time, there has been a warning for using the obsolete guard
tests (such as <code>list(L)</code> instead of <code>is_list(L)</code>. In Erlang/OTP 30, the
old guards will be removed from the language.</p>

<h2 id="stdlib">STDLIB</h2>

<ul>
  <li>There are new functions for randomly permutating a list: <code>rand:shuffle/1</code> and
<code>rand:shuffle_s/2</code>.</li>
</ul>

<h2 id="ssh">SSH</h2>

<ul>
  <li>The default key exchange algorithm is now mlkem768x25519-sha256, a hybrid
quantum-resistant algorithm combining ML-KEM-768 with X25519. This provides
protection against both classical and quantum computer attacks while
maintaining backward compatibility through automatic fallback to other
algorithms when peers don’t support it.</li>
</ul>

<p>For more details about new features and potential incompatibilities see the <a href="https://erlang.org/download/otp_src_29.0-rc1.readme">README</a>.</p>]]></content><author><name>Björn Gustavsson</name></author><category term="release," /><category term="OTP," /><category term="29.0-rc1," /><category term="Release" /><category term="Candidate" /><summary type="html"><![CDATA[OTP 29.0-rc1]]></summary></entry><entry><title type="html">Erlang/OTP 28.3 Release</title><link href="https://www.erlang.org/news/182" rel="alternate" type="text/html" title="Erlang/OTP 28.3 Release" /><published>2025-12-10T00:00:00+00:00</published><updated>2025-12-10T00:00:00+00:00</updated><id>https://www.erlang.org/news/182</id><content type="html" xml:base="https://www.erlang.org/news/182"><![CDATA[<h2 id="otp-283">OTP 28.3</h2>

<p>Erlang/OTP 28.3 is the second maintenance patch package for OTP 28, with mostly bug fixes as well as improvements.</p>

<h1 id="potential-incompatibilities">POTENTIAL INCOMPATIBILITIES</h1>

<ul>
  <li>Adjustment in ssh_file module allowing inclusion of Erlang/OTP license in test
files containing keys.</li>
</ul>

<h1 id="highlights">HIGHLIGHTS</h1>
<h2 id="ssl">ssl</h2>
<ul>
  <li>Support for MLKEM hybrid algorithms x25519mlkem768, secp384r1mlkem1024,
secp256r1mlkem768 in TLS-1.3
    <h2 id="ssl-public_key">ssl, public_key</h2>
  </li>
  <li>Added support in public_key and ssl for post quantum algorithm SLH-DSA.</li>
</ul>

<h2 id="erts-kernel">erts, kernel</h2>
<ul>
  <li>Support for the socket options TCP_KEEPCNT, TCP_KEEPIDLE, and TCP_KEEPINTVL
have been implemented for <code>gen_tcp</code>, as well as TCP_USER_TIMEOUT for both
<code>gen_tcp</code> and <code>socket</code>.</li>
</ul>

<h2 id="otp">OTP</h2>
<ul>
  <li>
    <p>Publish OpenVEX statements in https://erlang.org/download/vex/</p>

    <p>OpenVEX statements contain the same information as the OTP advisories, with
the addition of vendor CVEs for which Erlang/OTP is not affected. This is
important to silence vulnerability scanners that may claim Erlang/OTP to be
vulnerable to vendor dependency projects, e.g., <code>openssl</code>.</p>

    <p>OpenVEX statements will be published in https://erlang.org/download/vex/ where
there will be an OTP file per release, e.g.,
https://erlang.org/download/vex/otp-28.openvex.json.</p>

    <p>Erlang/OTP publishes OpenVEX statements for all supported releases, that is,
as of today, OTP-26, OTP-27, and OTP-28.</p>

    <p>The source SBOM tooling (oss-review-toolkit) has been updated to produce
source SBOM in SPDX v2.3 format, and the source SBOM now links OpenVEX
statements to a security external reference. This means that by simply
analyzing the source SBOM, everyone can further read the location of the
OpenVEX statements and further process them.</p>
  </li>
</ul>

<p>For details about bugfixes and potential incompatibilities see
the <a href="https://erlang.org/download/OTP-28.3.README">Erlang 28.3 README</a></p>

<p>The Erlang/OTP source can also be found at GitHub on the official Erlang repository,
https://github.com/erlang/otp</p>

<p>Download links for this and previous versions are found here:</p>

<ul>
  <li><a href="/downloads">https://www.erlang.org/downloads</a></li>
</ul>]]></content><author><name>Henrik Nord</name></author><category term="release," /><category term="OTP," /><category term="28.3" /><summary type="html"><![CDATA[OTP 28.3]]></summary></entry><entry><title type="html">Erlang/OTP 28.1 Release</title><link href="https://www.erlang.org/news/181" rel="alternate" type="text/html" title="Erlang/OTP 28.1 Release" /><published>2025-09-17T00:00:00+00:00</published><updated>2025-09-17T00:00:00+00:00</updated><id>https://www.erlang.org/news/181</id><content type="html" xml:base="https://www.erlang.org/news/181"><![CDATA[<h2 id="otp-281">OTP 28.1</h2>

<p>Erlang/OTP 28.1 is the first maintenance patch package for OTP 28, with mostly bug fixes as well as improvements.</p>

<h3 id="potential-incompatibilities">Potential incompatibilities:</h3>

<ul>
  <li>The internal <code>inet_dns_tsig</code> and <code>inet_res</code> modules have been fixed to TSIG
verify the correct timestamp.
In the process two undocumented error code atoms have been corrected to
<code>notauth</code> and <code>notzone</code> to adhere to the DNS RFCs. Code that relied on the
previous incorrect values may have to be corrected.</li>
</ul>

<h2 id="highlights">HIGHLIGHTS</h2>

<ul>
  <li>A User’s Guide to <code>dbg</code> is now available in the documentation.</li>
  <li>Support for quantum crypto signature algorithm ML-DSA and key exchange algorithm ML-KEM (ssl, public_key and crypto if built and linked with OpenSSL 3.5).</li>
</ul>

<p>For details about bugfixes and potential incompatibilities see
the <a href="https://erlang.org/download/OTP-28.1.README">Erlang 28.1 README</a></p>

<p>The Erlang/OTP source can also be found at GitHub on the official Erlang repository,
https://github.com/erlang/otp</p>

<p>Download links for this and previous versions are found here:</p>

<ul>
  <li><a href="/downloads">https://www.erlang.org/downloads</a></li>
</ul>]]></content><author><name>Henrik Nord</name></author><category term="release," /><category term="OTP," /><category term="28.1" /><summary type="html"><![CDATA[OTP 28.1]]></summary></entry></feed>