Opt-in requirements
The Kotlin standard library provides a mechanism for requiring and giving explicit consent for using certain elements of APIs. This mechanism lets library developers inform users of their APIs about specific conditions that require opt-in, for example, if an API is in the experimental state and is likely to change in the future.
To prevent potential issues, the compiler warns users of such APIs about these conditions and requires them to opt in before using the API.
Opt in to using API
If a library author marks a declaration from a library's API as requiring opt-in, you should give an explicit consent for using it in your code. There are several ways to opt in to such APIs, all applicable without technical limitations. You are free to choose the way that you find best for your situation.
Propagating opt-in
When you use an API in the code intended for third-party use (a library), you can propagate its opt-in requirement to your API as well. To do this, annotate your declaration with the opt-in requirement annotation of the API used in its body. This enables you to use API elements that require opt-in.
As you can see in this example, the annotated function appears to be a part of the @MyDateTime
API. So, such an opt-in propagates the opt-in requirement to the client code; its clients will see the same warning message and be required to consent as well.
Implicit usages of APIs that require opt-in also require opt-in. If an API element doesn't have an opt-in requirement annotation but its signature includes a type declared as requiring opt-in, its usage will still raise a warning. See the example below.
To use multiple APIs that require opt-in, mark the declaration with all their opt-in requirement annotations.
Non-propagating opt-in
In modules that don't expose their own API, such as applications, you can opt in to using APIs without propagating the opt-in requirement to your code. In this case, mark your declaration with @OptIn
passing the opt-in requirement annotation as its argument:
When somebody calls the function getDate()
, they won't be informed about the opt-in requirements for APIs used in its body.
Note that if @OptIn
applies to the declaration whose signature contains a type declared as requiring opt-in, the opt-in will still propagate:
To use an API that requires opt-in in all functions and classes in a file, add the file-level annotation @file:OptIn
to the top of the file before the package specification and imports.
Module-wide opt-in
If you don't want to annotate every usage of APIs that require opt-in, you can opt in to them for your whole module. To opt in to using an API in a module, compile it with the argument -opt-in
, specifying the fully qualified name of the opt-in requirement annotation of the API you use: -opt-in=org.mylibrary.OptInAnnotation
. Compiling with this argument has the same effect as if every declaration in the module had the annotation@OptIn(OptInAnnotation::class)
.
If you build your module with Gradle, you can add arguments like this:
If your Gradle module is a multiplatform module, use the optIn
method:
For Maven, it would be:
To opt in to multiple APIs on the module level, add one of the described arguments for each opt-in requirement marker used in your module.
Require opt-in for API
Create opt-in requirement annotations
If you want to require explicit consent to using your module's API, create an annotation class to use as an opt-in requirement annotation. This class must be annotated with @RequiresOptIn:
Opt-in requirement annotations must meet several requirements:
An opt-in requirement can have one of two severity levels:
RequiresOptIn.Level.ERROR
. Opt-in is mandatory. Otherwise, the code that uses marked API won't compile. Default level.RequiresOptIn.Level.WARNING
. Opt-in is not mandatory, but advisable. Without it, the compiler raises a warning.
To set the desired level, specify the level
parameter of the @RequiresOptIn
annotation.
Additionally, you can provide a message
to inform API users about special condition of using the API. The compiler will show it to users that use the API without opt-in.
If you publish multiple independent features that require opt-in, declare an annotation for each. This makes the use of API safer for your clients: they can use only the features that they explicitly accept. This also lets you remove the opt-in requirements from the features independently.
Mark API elements
To require an opt-in to using an API element, annotate its declaration with an opt-in requirement annotation:
Note that for some language elements, an opt-in requirement annotation is not applicable:
You cannot annotate a backing field or a getter of a property, just the property itself.
You cannot annotate a local variable or a value parameter.
Opt-in requirements for pre-stable APIs
If you use opt-in requirements for features that are not stable yet, carefully handle the API graduation to avoid breaking the client code.
Once your pre-stable API graduates and is released in a stable state, remove its opt-in requirement annotations from declarations. The clients will be able to use them without restriction. However, you should leave the annotation classes in modules so that the existing client code remains compatible.
To let the API users update their modules accordingly (remove the annotations from their code and recompile), mark the annotations as @Deprecated
and provide the explanation in the deprecation message.