Skip to Content
Working with the codebaseRemoving features

Removing features and integrations

Take the example features and optional vendors your app will not use out of the codebase with two scripts, before you configure anything.

Prerequisites

  • A clean git tree, so the diff is reviewable and reversible
  • Decisions on what to keep, recorded in the product brief

Remove a feature

yarn remove:feature create --dry-run yarn remove:feature create

Chat, Create and Scan are independent examples under src/features/. Pass one or several of chat, create and scan. --dry-run lists what would change without touching anything.

The script removes the feature’s registration in src/features/index.ts, its directory under src/features/, its route files, its edge function, its SQL block in the initial migration and its Maestro flow. It refuses when the feature is already gone, and stops at a file you have already reshaped by hand, naming it, so you finish that step yourself.

What stays: the shared services, the chat-media bucket and the quota tables. Chat and Scan draw on the same monthly allowance and Create needs Pro, so removing a history table does not change usage counting. Translation keys and analytics event declarations can keep unused entries. .maestro/smoke.yaml still asserts every tab; trim it to the tabs you keep.

Afterwards, apply the migration to your Supabase project, regenerate the types with PROJECT_REF=<ref> yarn supabase:db-types, and run yarn ci. Deleting a function’s source does not undeploy it; remove it from your Supabase project separately if it was already deployed.

Remove an integration

yarn remove:integration sentry --dry-run yarn remove:integration sentry

Pass one of sentry, onesignal or posthog. The script removes the vendor adapter, its config-plugin entry in app.config.js, its .env.example block, its lint fence and its setup reference. The port and its no-op stay, so every call site keeps compiling.

IntegrationWhat changesWhat remains for you
sentrysrc/services/crash-reporting/sentry.adapter.ts is deleted and the no-op wired into src/services/crash-reporting/index.ts. metro.config.js falls back to expo/metro-config. The Jest mock, the expo.install.exclude entry and the plugin block go toologError keeps working and logs to the console in development
onesignalsrc/services/push.ts becomes a no-op with the same exports. The onesignal-expo-plugin entry and the ONESIGNAL_MODE logic leave app.config.jsThe onboarding notifications screen asks for a permission nothing consumes; delete or repurpose it
posthogThe PostHog adapter and client are deleted, the no-op wired into src/services/analytics/analytics.ts, and AnalyticsProvider becomes a passthroughThe typed event registry stays, so trackEvent calls still compile

Neither script runs yarn remove. It prints the exact command; run it, then yarn ci.

Not removable by script

yarn remove:integration exits non-zero with the reason for these three:

IntegrationWhy
RevenueCatreact-native-purchases backs RevenueCatProvider, the Pro gate on Create, the paywall screens and the edge functions’ REVENUECAT_SECRET_KEY check, and Superwall bridges through it
Superwallexpo-superwall is wired into PaywallProvider, purchaseController and SubscriptionSync. Leave EXPO_PUBLIC_SUPERWALL_API_KEY_APPLE and EXPO_PUBLIC_SUPERWALL_API_KEY_GOOGLE unset and RevenueCat’s own paywall is used
Google sign-inThree auth screens render its button, config.js carries the OAuth client IDs, and app.config.js carries the plugin and its iOS pod settings

Each of them stays off while its keys are unset. What the script cannot do is remove the package from package.json.

Apple sign-in has no script either. Turning it off only makes sense for an app without Google sign-in, because Apple requires it alongside Google sign-in on iOS. Remove the Apple AuthButton from the sign-in and sign-up screens by hand and drop useSignInWithApple.

Never remove on a guess. The notifications primer is part of onboarding and comes out with push, so “I don’t think I need push” is a question to settle first.

Verify

yarn ci

Two CI checks prove that removal keeps working as the codebase changes:

CheckWhat it does
yarn check:feature-variantsCopies the source to temporary directories, runs yarn remove:feature there and checks Chat only, Create only, Scan only and the empty shell: docs, route types, typecheck, Jest and the remaining edge functions
yarn check:integration-variantsFor each of sentry, onesignal and posthog: makes the vendor’s packages unresolvable the way yarn remove leaves them, loads metro.config.js and app.config.js against that, runs the removal script, then typechecks, lints, tests and re-checks the docs and skill mirrors

Neither modifies your checkout or connects to a database. Run yarn check:db separately against the schema you keep.

Last updated on