Union
Guide

Declare features

A feature in Union is a funnel built from events your code declares: people who saw it, people who started it, people who finished it. Declaring it in code is a definition, not a suggestion — a build from TestFlight or the App Store creates the feature in the panel.

Declare a feature

let checkout = Union.feature("checkout")
checkout.screen("Checkout")                                   // discovery
checkout.start("checkout_started")                            // start
checkout.use("shipping_selected")                             // use
checkout.success("order_placed", properties: ["items": 3])    // success
checkout.failure("payment_failed", properties: ["reason": "card_declined"]) // failure

Define each feature key once (a constant or a static handle) and reuse it — a typo creates a second feature.

Roles

RoleMeaning
discoverySaw that the feature exists and has not tried it yet. feature.screen(…) sets it for you.
startMade an attempt whose outcome is not known yet. The funnel’s denominator — without it there is no funnel.
useWorking inside the feature; may happen many times per attempt. Counted towards adoption, not a step of its own.
successThe feature gave the person what they came for. Once per attempt.
failureThe attempt failed from the person’s point of view: permission denied, no results, a save that did not happen.

The funnel in the panel has three steps — Discovery → Adoption → Success — where adoption counts everyone who started or used the feature.

Rules the server enforces

  • One event name is one (feature, role) pair everywhere in the code. The same name as success in one place and failure in another is a conflict the panel shows and never resolves for you.
  • Giving up is its own event name (onboarding_abandoned), not a property on the completed event.
  • A feature is something a person can fail to adopt. A core surface everyone touches on day one (home, items) reports 100% adoption and says nothing — send those events without a feature.
  • Declare only what you instrument. A declared feature nothing emits reads as zero adoption.
Worth knowing
Development builds do not create features

A DEBUG build only pre-fills the feature editor, so experimenting locally never adds features to the panel. Declarations from TestFlight and App Store builds do.

Changing a feature later

The SDK only ever adds: a new event or role in a later build joins the feature, and nothing you set in the panel is removed or overwritten. A feature you created by hand with the same name is adopted instead of duplicated. When the panel’s definition changes, history is recomputed from the raw events.

Suggestions

Events you did not declare are grouped by name (comment_opened, comment_posted → comment) into suggestions. Nothing is created until you approve one under Features → Review.

Updated Oct 23, 2026 · Markdown