Features

Your app is full of features — a screen, a menu item, a button, an export, a whole flow. Normally whether each one is on, off, in beta, or behind a paywall is baked into the build you ship, so changing it means another release. Onelo Features is a remote control panel for the features in your own app. The feature itself stays in your code; Onelo controls who sees it and how — live, from the dashboard, without shipping a new build or waiting on an app-store review.

The loop is simple: you declare features in code in your app's codebase; the Onelo Features SDK reports them to the dashboard; and there you manage and decide each feature's visibility — on for everyone, locked behind a plan, in beta for a few testers, badged as new, teased as coming-soon, or hidden entirely. Click Deploy and connected apps reflect the change within seconds. It works the same in your client app (Swift, JS…) and your backend (Python…).

Reach for it when you want to:

  • Ship dark, switch on later — merge unfinished work behind a hidden feature and flip it the day it's ready.
  • Beta to a few — open a feature to specific testers or one plan, watch how it goes, then roll it out to everyone.
  • Gate by plan — make a feature part of a paid tier; users on other plans see a locked padlock or an upgrade prompt.
  • Kill a problem instantly — something broke in production? Hide the feature in seconds, with no release.

Everything you edit happens in one of two parallel worlds — Test and Live. You shape and try features in Test, then Promote them to Live when you're happy. Production users only ever read the Live world.

What your app sees — the status

Whatever you set up, your code only ever deals with one thing: for each feature, the SDK resolves a single status for the current user, and your UI renders by it. Render by status, not a boolean — that keeps locked, coming-soon and upsell features visible (a padlock or a badge) instead of vanishing.

Status the app readsWhat to render
enabledVisible and fully usable.
newVisible and usable, with a NEW badge.
betaVisible and usable, with a BETA badge.
coming_soonVisible but not usable — a “coming soon” teaser. As a plan-gated cell it can also carry a tap-to-upgrade (same CTA rule as greyed / upsell).
greyedVisible but locked — a padlock. Tap-to-upgrade when the feature’s CTA toggle is on (default) and a higher plan grants it; greyed just omits the “Available in …” tease.
upsellVisible, locked, with an “Available in …” tease — tapping opens your upgrade flow when the CTA toggle is on (default) and a higher plan unlocks it.
hiddenNot rendered at all.

These are the values the SDK returns — and what helpers like isEnabled / isVisible read for you. See SDK integration.

Where that status comes from — two layers

You produce that resolved status from two separate dashboard controls. They sit on different layers, and — on purpose — don't use the exact same list of options:

LayerWhat you setOptions
Feature statusRegistry · one per featureThe baseline everyone gets — or “hand off to the rules”.ActiveNewBetaComing SoonGreyedTargetedHidden
Plan & user visibilityPlans / Targeting · per plan or userWhat a specific plan or user sees. Plan rules apply to any non-hidden feature once the paywall is on; per-user rules require Targeted.EnabledNewBetaComing SoonLockedUpsellHidden
The lists differ by one swap. Feature status has Targeted but no Upsell; plan visibility has Upsell but no Targeted. Targeted means "defer fully to the rules — including per-user overrides"; an Upsell only means something relative to a plan. The shared ones (new, beta, coming-soon, the lock) mean the same on both layers. (The lock is the value greyed, shown as Greyed in the Registry and Locked in plan visibility.)

So: set a feature's status in the Registry; set it to Targeted to let plan and targeting rules decide per user; and use Inspect to see which layer won for any user.

How a feature reaches your app

1

You declare it in code

Reference a feature by name wherever your code runs — in the app itself (desktop, mobile or web) and/or a backend service; a desktop app is often both at once. For example onelo.features.feature("advanced-export"). See SDK integration.
2

The SDK reports it — while running in Test

Test and Live are the two worlds from above: Test is your sandbox, Live is what production reads. Which one a running app belongs to is set by the ONELO_FEATURE_ENVIRONMENT variable — not by which key you hold. While an app runs in Test, the SDK reports the feature names it uses and they appear in the Registry as hidden. Discovery only ever writes in Test — Live never grows on its own. See Discovery & Deploy access.
3

You set its status, plans and targeting

Flip it on, gate it to a plan, bundle it in a pack, or open it to specific users in Targeting.
4

Deploy to Test

Edits stage as pending until you click Deploy to test — then test builds receive the new snapshot live. Try it for real before it touches production.
5

Promote to Live, then Deploy to Live

Promote copies your Test setup into Live (a summary lets you hold parts back); deploying Live publishes it to your real users.
6

The SDK resolves it, and stays in sync

Your app reads the status and renders. When you deploy again, connected apps update over their live connection within seconds — no restart, no new build.

The dashboard, tab by tab

Open your app → Features. Pick an Application, choose the Test/Live environment, then work across four tabs (plus Inspect):

Set it up

Before you can manage features, integrate the SDK: install it, add the snippet for your language, place it in your code, and reference your features by name — then run the app once in Test so the SDK reports them. The step-by-step lives in SDK integration and Discovery. Plan gating additionally needs the Paywall turned on, with plans defined.
Features — Onelo Docs