Feature Flags iOS
PostHogOfficialCreated by PostHog
- Skill
- Tool integration
- Data and AI
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured approach to implementing PostHog feature flags within iOS applications. It covers the necessary setup for Swift projects, including environment variable management, Swift Package Manager (SPM) configuration, and platform-specific build settings. The guide emphasizes maintaining clean code by minimizing flag dispersion and ensuring consistent user experiences through proper identification and evaluation strategies.
What it does
- Provides guidelines for secure configuration using environment variables.
- Details the manual setup of SPM dependencies for iOS projects.
- Outlines best practices for flag naming and code organization.
- Offers instructions for handling network settings in sandboxed environments.
- Explains how to integrate feature flag logic into existing iOS codebases.
When to use it
- When you need to implement feature flagging in a native iOS application.
- When you want to manage feature rollouts or experiments using PostHog.
- When you need to configure PostHog SDK dependencies in an Xcode project.
- When you are looking for best practices to avoid UI flicker or performance issues with flags.
Advantages
- Promotes secure handling of sensitive configuration keys.
- Ensures consistent flag evaluation across different app sessions.
- Helps maintain clean, modular code by centralizing flag logic.
- Provides specific technical guidance for Xcode and SPM integration.
Usage examples
- “How do I add the PostHog SDK to my iOS project using SPM?”
- The agent provides the steps to create the required PBXBuildFile, XCSwiftPackageProductDependency, and XCRemoteSwiftPackageReference objects in your project.pbxproj file.
- “What is the best way to store my PostHog project token in an iOS app?”
- The agent instructs you to use an environment variable accessed via a PostHogEnv enum, ensuring the token is not hardcoded in your source code.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/posthog/feature-flags-ios/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip feature-flags-ios.zip -d .agents/skills
Documentation by PostHog
PostHog feature flags for iOS
This skill helps you add PostHog feature flags to iOS applications.
Reference files
references/ios.md- Ios feature flags installation - docsreferences/adding-feature-flag-code.md- Adding feature flag code - docsreferences/best-practices.md- Feature flag best practices - docs
Consult the documentation for API details and framework-specific patterns.
Key principles
Environment variables: Always use environment variables for PostHog keys. Never hardcode them.
Minimal changes: Add feature flag code alongside existing logic. Don't replace or restructure existing code.
Boolean flags first: Default to boolean flag checks unless the user specifically asks for multivariate flags.
Server-side when possible: Prefer server-side flag evaluation to avoid UI flicker.
PostHog MCP tools
Check if a PostHog MCP server is connected. If available, look for tools related to feature flag management (creating, listing, updating, deleting flags). Use these tools to manage flags directly in PostHog rather than requiring the user to do it manually in the dashboard.
Framework guidelines
Read configuration from environment variables via a
PostHogEnvenum with avaluecomputed property that callsProcessInfo.processInfo.environment[rawValue]andfatalErrors if missing — cases should beprojectToken = "POSTHOG_PROJECT_TOKEN"andhost = "POSTHOG_HOST", set in the Xcode scheme's Run environment variablesWhen adding SPM dependencies to project.pbxproj, create three distinct objects with unique UUIDs — a
PBXBuildFile(withproductRef), anXCSwiftPackageProductDependency(withpackageandproductName), and anXCRemoteSwiftPackageReference(withrepositoryURLandrequirement). The build file goes in the Frameworks phasefiles, the product dependency goes in the target'spackageProductDependencies, and the package reference goes in the project'spackageReferences.Check the latest release version of posthog-ios at
https://github.com/PostHog/posthog-ios/releasesbefore setting theminimumVersionin the SPM package reference — do not hardcode a stale versionIf the project uses App Sandbox (macOS), add
ENABLE_OUTGOING_NETWORK_CONNECTIONS = YESto the target's build settings so PostHog can reach its servers — do NOT disable the sandbox entirely
Files
- ATTRIBUTION.mdAdded by AutoGineer951 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md2.5 KiB
- references/adding-feature-flag-code.md108.7 KiB
- references/best-practices.md7.9 KiB
- references/ios.md3.5 KiB
references/best-practices.md
Feature flag best practices - Docs
1. Use a reverse proxy
Ad blockers have the potential to disable your feature flags, which can lead to bad experiences, such as users seeing the wrong version of your app, or missing a new feature rollout.
To avoid this, deploy a reverse proxy, which enables you to make requests and send events to PostHog Cloud using your own domain.
This means that requests are less likely to be intercepted by tracking blockers, and your feature flags are more likely to work as intended. You'll also capture more usage data.
PostHog offers a free managed reverse proxy, or you can run your own. See our reverse proxy docs for more.
2. Call your flag in as few places as possible
It should be easy to understand how feature flags affect your code. The more locations a flag is in, the more likely it is to cause problems. For example, a developer could remove the flag in one place but forget to remove it in another.
If you expect to use a feature flag in multiple places, it's a good idea to wrap the flag in a single function or method. For example:
JavaScript
PostHog AI
function useBetaFeature() {
return posthog.isFeatureEnabled('beta-feature')
}3. Targeting
PostHog evaluates flags based on the user's distinct ID, having different IDs can cause the same user to receive different flag values across different sessions, devices, and platforms. By identifying them, you can ensure consistent flag values.
The same applies to identifying groups for group-level flags.
For flags targeting anonymous users, such as signup flows or landing page experiments, consider using device bucketing instead. This evaluates the flag based on the device ID, ensuring a consistent experience on the device even after the user logs in.
4. Use server-side local evaluation for faster flags
Evaluating feature flags requires making a request to PostHog for each flag. However, you can improve performance by evaluating flags locally. Instead of making a request for each flag, PostHog will periodically request and store feature flag definitions locally, enabling you to evaluate flags without making additional requests.
Evaluate flags locally when possible, since this enables you to resolve flags faster and with fewer API calls. See our docs on local evaluation for more details.
5. Bootstrap flags on the client to make them available immediately
Since there is a delay between initializing PostHog and fetching feature flags, feature flags are not always available immediately. This makes them unusable if you want to do something like redirecting a user to a different page based on a feature flag.
To have your feature flags available immediately, you can initialize PostHog with precomputed values until it has had a chance to fetch them. This is called bootstrapping.
See our docs on bootstrapping for more details on how to do this.
6. Naming tips
Good naming conventions for your flags makes them easier to understand and maintain. Below are tips for naming your flags:
Use descriptive names. For example,
is_v2_billing_dashboard_enabledis much clearer thanis_dashboard_enabled.Use name "types". This helps organize them and makes their purpose clear. Types might include experiments, releases, and permissions. For example, instead of
new-billing, they would benew-billing-experimentornew-billing-release.Name flags to reflect their return type. For example,
is_premium_userfor a boolean,enabled_integrationsfor an array, orselected_themefor a single string.Use positive language for boolean flags. For example,
is_premium_userinstead ofis_not_premium_user. This helps avoid double negatives when checking the flag value (e.g.if !is_not_premium_useris confusing).
7. Roll out progressively
When testing a change behind a feature flag, it is best to roll it out to a small group of users and increase that group over time. This is also known as a phased rollout. It enables you to identify any potential issues ahead of the full release.
For example, at PostHog we often roll out the flag to just the responsible developer. It then moves on to the internal team, then beta users, and finally into a full rollout. This enables us to test in production, get multiple rounds of feedback, identify issues, and polish the feature before the full release.
8. Clean up after yourself
Leaving flags in your code for too long can confuse future developers and create technical debt, especially if it's already rolled out and integrated. Be sure to remove stale flags once they are completely rolled out or no longer needed.
When you have many flags to clean up, use bulk delete to select and delete multiple flags at once. Select flags using checkboxes (shift-click to select a range), or filter by name or status and use "select all matching" to select all flags that match your criteria. PostHog validates that flags aren't used by experiments, early access features, or other dependent flags before deletion.
9. Fallback to working code
It's possible that a feature flag will return an unexpected value. For example, if the flag is disabled or failed to load due to a network error.
In this case, its best to check that the feature flag returns a valid expected value before using it. If it isn't, fallback to working code.
10. Use dependencies for complex rollouts
For sophisticated feature rollouts, consider using feature flag dependencies where one flag's activation depends on another flag's state. This is useful for:
Enabling complex features only after foundational components are active
Running experiments only on users with specific features enabled
Creating safety mechanisms where critical flags must be enabled first
When using dependencies, keep the dependency chains simple and avoid circular dependencies.
11. Reducing your bill
We aim to be significantly cheaper than our competitors. To help you reduce your bill, we've created a dedicated guide to estimating and reducing your feature flag costs.
12. Consistent flag evaluations across frontend and backend
For feature flags with flag persistence enabled and used across both your frontend and backend, you will need to do one of the following to ensure the evaluation result of the flag is consistent between both environments:
Identify the user on the frontend and use the same identified distinct ID when evaluating the flag on the backend.
JavaScript
PostHog AI
// Frontend: Identify the user
posthog.identify('user123')
// Backend: Use the same distinct ID
const flagValue = await posthog.getFeatureFlag('my-flag', 'user123')If you are unable to call identify on the frontend, and only have access to the anonymous distinct ID when evaluating the flag on the backend, you can include the anonymous distinct ID as a person property override in the
getFeatureFlagcall.
JavaScript
PostHog AI
// Frontend: Get the anonymous ID (before identify is called)
const anonId = posthog.getAnonymousId()
// Backend: Pass the anonymous ID as a person property override
const flagValue = await posthog.getFeatureFlag(
'my-flag',
'user123', // identified distinct ID
{
personProperties: {
$anon_distinct_id: anonId
}
}
)Community questions
Ask a question
Was this page useful?
HelpfulCould be better
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an MCP server
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- PostHog
- Publisher
- PostHog (Official)
- Source
- PostHog/skills · skills/posthog/feature-flags/skills/ios · commit a5d30e7
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Also distributed in
- PostHog/skills
AutoGineer is not affiliated with or endorsed by PostHog or PostHog.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download feature-flags-ios.zip