Feature Flags (PostHog)
Feature flags are managed through PostHog to control feature rollouts, A/B testing, and gradual releases.
Setup
PostHog is initialized at the app root in app/_layout.tsx:
tsx
import { PostHogProvider } from "posthog-react-native";
import { POSTHOG_API_KEY } from "@/constants/config";
<PostHogProvider
apiKey={POSTHOG_API_KEY}
options={{
host: "https://us.i.posthog.com",
enableSessionReplay: true,
preloadFeatureFlags: true,
sendFeatureFlagEvent: true,
}}
>
{/* App content */}
</PostHogProvider>Using Feature Flags
Import the useFeatureFlag hook from posthog-react-native:
tsx
import { useFeatureFlag } from "posthog-react-native";
export default function MyComponent() {
const showNewFeature = useFeatureFlag("new_feature");
return (
<>
{showNewFeature && <NewFeatureComponent />}
</>
);
}Active Feature Flags
| Flag | Purpose | Location |
|---|---|---|
dark_mode | Dark theme toggle | Settings |
push_notifications | Push notification settings | Settings |
custom_app_icon | Custom app icon selection | Settings |
reading_reminders | Reading reminder notifications | Settings |
private_profile | Private profile option | Settings |
export_data | Data export functionality | Settings |
delete_account | Account deletion feature | Settings |
in_app_support | In-app support/help | Settings |
book_clubs | Book clubs feature | Home, Profile |
stickers | Sticker collection feature | Profile |
book_reviews | Book review feature | Book Detail |
book_editions | Book edition selection | Book Detail |
Adding a New Feature Flag
- Create the flag in PostHog - Go to PostHog dashboard > Feature Flags > New Feature Flag
- Use in code - Add the
useFeatureFlaghook in your component:
tsx
const showMyFeature = useFeatureFlag("my_feature_flag");- Conditional rendering - Wrap the feature in a conditional:
tsx
{showMyFeature && <MyFeature />}Event Tracking
Use usePostHog to track events when users interact with features:
tsx
import { usePostHog } from "posthog-react-native";
export default function BookScreen() {
const posthog = usePostHog();
const handleAddToLibrary = () => {
posthog.capture("mark_tbr", {
isbn13: book.isbn13,
title: book.title,
});
};
}Tracked Events
| Event | Description |
|---|---|
onboarding_signup_sent | User initiated signup |
user_signed_in | User completed authentication |
onboarding_complete | User finished onboarding |
mark_tbr | Book added to Want to Read |
mark_currently_reading | Book marked as currently reading |
mark_finished | Book marked as finished |
mark_favorite | Book marked as favorite |
book_shared | User shared a book |
buy_book_clicked | User clicked buy link |
reading_goal_created | User created reading goal |
reading_goal_modified | User updated reading goal |
user_signed_out | User signed out |
Screen Tracking
Screens are automatically tracked in the layout files:
tsx
// app/(tabs)/_layout.tsx
import { usePostHog } from "posthog-react-native";
export default function TabLayout() {
const posthog = usePostHog();
const pathname = usePathname();
const params = useGlobalSearchParams();
useEffect(() => {
posthog.screen(pathname, params);
}, [pathname, params]);
}User Identification
Users are identified after authentication in the auth store:
tsx
posthog.identify(user.id, {
email: user.email,
new: !onboardingComplete,
});Best Practices
- Use descriptive flag names -
book_reviewsnotfeature_1 - Group related flags - Settings flags are all checked together
- Include properties in events - Always include relevant context (book ID, title, etc.)
- Clean up old flags - Remove flags from code after features are fully rolled out
- Test both states - Verify behavior when flag is on and off