Feature flags
Evaluate feature flags in your application using the Atono SDK
The Atono SDK lets you evaluate feature flags in your application to control which features are active in a given environment. Atono feature flags are based on OpenFeature, an emerging standard for feature flagging that supports multiple platforms.
This topic assumes you’ve already installed and initialized an Atono SDK. For setup instructions, see Get started with the Atono SDK.
For details on how to generate code samples for a flag and find your environment key, see Implement a feature flag in your application.
Choose clear flag names
Use names that describe what enabling the flag does. This helps developers understand the flag in code and reduces the chance that someone connects a story to a flag intended for something else.
For related flags, consider using a shared prefix. For example:
workflow_manage_steps
workflow_indicate_staleness
workflow_project_done_time
workflow_report_cycle_timeA shared prefix keeps related flags grouped in alphabetized lists and makes them easier to find.
Avoid using one broad flag for too many distinct behaviours. More focused flags let you release parts of an initiative independently and connect each flag to the stories it controls.
Evaluate a feature flag
Use the feature flag’s name to evaluate it in your application. Each evaluation includes a fallback value that the SDK returns if it can’t determine a value for the flag, such as when the flag doesn’t exist or no configuration has been retrieved.
Web
Get the feature flag client, then call getBooleanValue():
const featureFlags = await atono.getFeatureFlags();
const isEnabled = featureFlags.getBooleanValue(
'flag_name',
false
);Replace flag_name with the feature flag’s name in Atono.
The second argument, false, is the fallback value. For more information, see Fallback value.
React
Use the useFeatureFlag() hook in a component inside <AtonoProvider>:
import { useFeatureFlag } from '@atono-io/react-sdk';
function ChildComponent() {
const isEnabled = useFeatureFlag()
.getBooleanValue('flag_name', false);
return isEnabled
? <Enabled />
: <Disabled />;
}Replace flag_name with the feature flag’s name in Atono.
The second argument, false, is the fallback value. For more information, see Fallback value.
Java
Call getBooleanValue() from the Atono feature flag client:
boolean isEnabled = atono.getFeatureFlags().getBooleanValue(
"flag_name",
false
);Replace flag_name with the feature flag’s name in Atono.
The second argument, false, is the fallback value. For more information, see Fallback value.
If the flag is configured by customer or location, include evaluation context when evaluating it. See Set evaluation context.
Node.js
If the flag is configured by customer, create evaluation context for the current request and pass it when evaluating the flag:
const isEnabled = featureFlags.getBooleanValue(
'flag_name',
false
);Replace flag_name with the feature flag’s name in Atono.
The second argument, false, is the fallback value. The third argument provides context for the current request. For more information, see Fallback value.
If the flag is configured by customer or location, include evaluation context when evaluating it. See Set evaluation context.
Set evaluation context
Evaluation context provides information Atono can use when determining whether a feature flag is enabled, such as the customer or location associated with the current user or request.
How you provide context depends on whether you’re using a client-side or server-side SDK.
Web
The Web SDK detects location automatically from the user’s IP address.
To provide other context, such as a customer identifier, set the context after initialization:
await atono.setContext({
customer: 'your-customer-id'
});Replace your-customer-id with the customer identifier used in your application.
Set the context when your application initializes or when the current customer changes.
React
The React SDK detects location automatically from the user’s IP address.
Provide other context through <AtonoProvider>:
import { AtonoProvider } from '@atono-io/react-sdk';
function RootComponent() {
const evaluationContext = {
customer: 'your-customer-id'
};
return (
<AtonoProvider
environmentKey="<your-environment-key>"
evaluationContext={evaluationContext}
>
<App />
</AtonoProvider>
);
}Replace your-customer-id with the customer identifier used in your application.
Java
The Java SDK doesn’t store evaluation context globally. When a flag is configured by customer or location, create context for the current request and pass it with the evaluation:
import io.atono.sdk.context.EvaluationContext;
var context = EvaluationContext.builder()
.customer("your-customer-id")
.location(atono.getLocationProvider().fromClientIp(clientIp))
.build();
boolean isEnabled = atono.getFeatureFlags().getBooleanValue(
"flag_name",
false,
context
);Replace:
flag_namewith the feature flag’s name in Atonoyour-customer-idwith the customer identifier used in your applicationclientIpwith the client’s IP address for the current request
Your application is responsible for identifying the appropriate customer and client IP address for the current request. How you manage evaluation context depends on your application architecture. For example, you might cache it for a session or create it for each request.
Pass the client’s IP address, not the IP address of the application server.
The location provider supports IPv4 and IPv6 addresses. If it can’t determine a location from the supplied IP address, the SDK continues evaluating the flag without location context.
Node.js
The Node.js SDK doesn’t store evaluation context globally. When a flag is configured by customer, add the evaluation context to the flag evaluation for the current request:
const isEnabled = featureFlags.getBooleanValue(
'flag_name',
false,
{
customer: 'your-customer-id',
location: atono.getLocationService().fromClientIp(clientIp)
}
);Replace:
flag_namewith the feature flag’s name in Atonoyour-customer-idwith the customer identifier used in your applicationclientIpwith the client’s IP address for the current request
Your application is responsible for identifying the appropriate customer and client IP address for the current request. How you manage evaluation context depends on your application architecture. For example, you might cache it for a session or create it for each request.
Pass the client’s IP address, not the IP address of the application server.
The location provider supports IPv4 and IPv6 addresses. If it can’t determine a location from the supplied IP address, the SDK continues evaluating the flag without location context.
SDK resilience and fallback behavior
The Atono SDK uses multiple fallback mechanisms to keep your application running if it temporarily loses connection to Atono.
Configuration snapshot
When your application starts, the SDK fetches a snapshot of all feature flags and slices. The snapshot is stored in memory and used for evaluations, so flag checks happen locally and don’t require live communication with Atono.
If Atono becomes unavailable after the SDK has retrieved its configuration, evaluations continue using the last known configuration.
Fallback value
Each flag evaluation includes a fallback value. If the SDK can’t retrieve the configuration at startup, or your application evaluates a flag that doesn’t exist in the workspace, it returns the fallback value supplied in your code.
For example, false means the feature is off by default.
atono.getFeatureFlags.getBooleanValue(
'flag_name',
false
);atono.getFeatureFlags().getBooleanValue(
"flag_name",
false
);Keep fallback values consistent
A flag may be evaluated in several places in your application. Use the same fallback value everywhere the flag is checked.
Different fallback values can leave some parts of a feature enabled and others disabled if the SDK can’t retrieve the flag configuration or the flag is removed.
To keep the fallback value consistent, centralize the evaluation in a shared function:
function isWorkflowEnabled() {
return atono.getFeatureFlags.getBooleanValue(
'workflow',
false
);
}class FeatureService {
private Atono atono;
// ...SDK initialization or injection...
public boolean isWorkflowEnabled() {
return this.atono.getFeatureFlags()
.getFeatureFlags("workflow", false);
}
}Use the shared function wherever your application checks the flag:
if (isWorkflowEnabled()) {
// Turn on the workflow-related behaviour
}if (featureService.isWorkflowEnabled()) {
// Turn on the workflow-related behaviour
}This also gives you one place to change the fallback value later.
Polling for configuration updates
After initialization, the SDK polls for updated flag configurations at regular intervals of 5 seconds. When a new configuration is available, it automatically replaces the previous one.
Flag evaluations continue using the locally stored configuration while Atono is temporarily unavailable.
Evaluation event reporting
Each time a flag is evaluated, the SDK queues an event to report back to Atono. These events are used for:
- “Last evaluated” timestamps shown in the flag list
- Slice customer suggestions
Events are posted to Atono at regular intervals. If Atono is temporarily unreachable, the SDK continues to queue events and sends them when the connection is restored.
If the application shuts down before events are posted, such as when a user closes a browser tab, those events may be lost. This does not affect flag evaluation.
Updated about 10 hours ago

