Skip to content
Skip to content
Goodspeed

Build apps with RevenueCat

RevenueCat is wired into every Goodspeed app that has in-app purchases: native SDK, paywall screen, subscription hooks, and PostHog analytics. Goodspeed generates RevenueCat as a standard part of every app, so the output is a working codebase from day one, not a scaffold you have to finish yourself.

WHAT GETS GENERATED

Built into every RevenueCat build

Every app Goodspeed generates with RevenueCat includes these production-ready patterns, wired together from the first build.

ItemDescriptionStrength
lib/revenuecat.ts conditional native importreact-native-purchases is imported via require() at runtime so the bundle does not crash on web (where IAP is unavailable), and the module is a no-op instead.Architecture
hooks/useSubscription.ts entitlement hookA React hook that reads the user's active entitlements from RevenueCat and returns isPremium, tier, and expiresAt for any component that needs paywall checks.Hook
hooks/usePaywall.ts purchase flow hookWraps the RevenueCat offerings fetch and Purchases.purchasePackage call. Handles loading state, error handling, and PostHog event tracking in one place.Hook
app/(modal)/paywall.tsx paywall screenA full-screen modal paywall with offerings fetched from RevenueCat, feature list, pricing tiers, and a restore purchases button.Screen
gasConfig.backend.revenuecat key configiOS and Android RevenueCat API keys live in gas.config.ts under backend.revenuecat and are read by lib/revenuecat.ts on initialization.Configuration

Source: gas-template repository · Subscriptions and In-App Purchases

REAL GENERATED CODE

A snippet from a RevenueCat app the studio shipped

This pattern comes directly from the gas-template codebase, the foundation every Goodspeed app is generated on. The studio generates RevenueCat code like this for every app in the pipeline, not just a hello-world scaffold.

  1. Conditional IAP init

    // lib/revenuecat.ts: conditional native import + init
    let Purchases: typeof import('react-native-purchases').default | null = null;
    if (!isWeb) {
      try {
        Purchases = require('react-native-purchases').default;
      } catch { /* module not available */ }
    }
    
    export async function initRevenueCat(): Promise<void> {
      if (isWeb || !Purchases) return;
      if (!gasConfig.features.inAppPurchases.enabled) return;
      const apiKey = Platform.OS === 'ios'
        ? gasConfig.backend.revenuecat.iosKey
        : gasConfig.backend.revenuecat.androidKey;
      if (!apiKey) return;
      await Purchases.configure({ apiKey });
    }
GDaily Allergens

Today's log

Gluten
Tree nuts
Shellfish
Dairy
HomeScanLogProfile

START WITH REVENUECAT

Your RevenueCat app, generated