Cached at:
05/13/26, 12:18 PM
# Erlang/OTP 29.0 - Erlang/OTP
Source: [https://www.erlang.org/news/188](https://www.erlang.org/news/188)
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\.
Many thanks to all contributors\!
## Highlights[\#](https://www.erlang.org/news/188#highlights)
- Added support for`\-unsafe`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,`xref`can now be used to find calls to unsafe functions and functions that lack documentation\.
- 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\.
- The SFTP subsystem is no longer enabled by default when starting an SSH daemon\.
- In SSL, the post quantum hybrid algorithm x25519mlkem768 is now the most preferred key exchange group in the default configuration\.
- The module`io\_ansi`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\.
- The new`ct\_doctest`module allows the user to test documentation examples in Erlang module docs and documentation files\.
- The`ignore\_xref`attribute has been handled as a post\-analysis filter by build tools such as Rebar3\. In this release, \[`xref`\] itself does the filtering, ensuring that all tooling that calls`xref`for any purpose can rely on these declarations to just work\.
## General[\#](https://www.erlang.org/news/188#general)
- In the default code path for the Erlang system, the current working directory \(`\.`\) is now in the last position instead of the first\.
- There is no longer a 32\-bit Erlang/OTP build for Windows\.
## New language features[\#](https://www.erlang.org/news/188#new-language-features)
- Native records as described in[EEP\-79](https://github.com/erlang/eep/pull/81)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\.
- The new`is\_integer/3`guard BIF makes it possible to easily verify that a value is both an integer and within a certain range\. For example:`is\_integer\(I, 0, 100\)`
- Multi\-valued comprehensions according to[EEP 78](https://www.erlang.org/eeps/eep-0078)are now supported\. For example,`\[\-I, I \|\| I <\- \[1, 2, 3\]\]`will produce`\[\-1,1,\-2,2,\-3,3\]`\.
- By enabling the`compr\_assign`feature, it is now possible to bind variables in a comprehensions\. For example:`\[H \|\| E <\- List, H = erlang:phash2\(E\), H rem 10 =:= 0\]`
## Compiler and JIT improvements[\#](https://www.erlang.org/news/188#compiler-and-jit-improvements)
- In the documentation for the \[`compile`\] module, there is now a section with recommendations for implementors of languages running on the BEAM\.
- The JIT now generates better code for matching or creating binaries with multiple little\-endian segments\.
- The compiler will generate more efficient code for map comprehensions with constant values that don’t depend on the generator\. Example:`\#\{K =\> 42 \|\| K <\- List\}`
## Compiler warnings[\#](https://www.erlang.org/news/188#compiler-warnings)
There are several new compiler warnings enabled by default\. For each such warning, there is an option to disable it\.
- There will now be a warning when using the`catch`operator, which has been deprecated for a long time\. It is recommended to instead use`try`…`catch`but is also possible to disable the warning by using the`nowarn\_deprecated\_catch`option\.
- There will now be a warning when exporting variables out of a subexpression\. For example:`file:open\(File, AllOpts = \[write, \{encoding,utf8\}\]\)`\. This warning can be disabled using the`nowarn\_export\_var\_subexpr`compiler option\.
- The compiler will now warn for uses of the`and`and`or`operators\. This warning can be disabled using the`nowarn\_obsolete\_bool\_op`compiler option\.
- The compiler will now warn for matches such as`\{a,B\} = \{X,Y\}`, which is better written as`\{a=X,B=Y\}`\. This warning can be disabled using the`nowarn\_match\_alias\_pats`option\.
For a long time, there has been a warning for using the obsolete guard tests \(such as`list\(L\)`instead of`is\_list\(L\)`\. In Erlang/OTP 30, the old guards will be removed from the language\.
## STDLIB[\#](https://www.erlang.org/news/188#stdlib)
- There are new functions for randomly permutating a list:`rand:shuffle/1`and`rand:shuffle\_s/2`\.
## SSH[\#](https://www.erlang.org/news/188#ssh)
- 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\.
For a full list and more details about new features and potential incompatibilities see the[README](https://erlang.org/download/otp_src_29.0.readme)\.