BoilerplateHub

React Native + Supabase + Supabase Auth + RevenueCat

React Native with Supabase, Supabase Auth and RevenueCat is the subscription mobile configuration the app stores actually permit. RevenueCat normalizes receipts and entitlements across both stores, Supabase holds the application data, and the app never touches a card. It suits a consumer app selling premium features or gated content by subscription.

React Native SupabaseSupabase AuthRevenueCat

Database

Supabase

In this stack Postgres is not the source of billing truth, RevenueCat is, so resist rebuilding subscription logic in your schema. Store the RevenueCat app user ID against the Supabase user and cache the current entitlement for server-side checks, refreshed by RevenueCat webhooks into an edge function. Row level security policies on premium tables then read that cached entitlement, which stops a modified client from unlocking content by lying about its own purchase state.

Authentication

Supabase Auth

Supabase Auth gives you a stable user ID before the first purchase, and that is what makes cross-device restore work. Set the Supabase user ID as the RevenueCat app user ID at login rather than letting RevenueCat generate an anonymous one, otherwise someone who reinstalls and signs in arrives as a fresh identity with no purchases attached. Handle the alias case too, where a person subscribes before ever creating an account.

Payments

RevenueCat

RevenueCat exists because store receipt validation, renewals, grace periods, billing retries and upgrades are genuinely difficult across two different platforms. It reduces all of that to one entitlement check the client and your server can both trust. Store commission still applies underneath, and you accept a third party in the path, in exchange for never writing receipt parsing or maintaining a subscription state machine you did not design.

What to watch out for

Store commission sits on top of everything, so your pricing has to survive that cut before you build. And because entitlement state arrives asynchronously, the client SDK and your Supabase cache can disagree for a moment right after a purchase. Gate the UI on the RevenueCat client result so it feels instant, but gate the actual rows in row level security on the server-side copy and let the webhook settle the difference.

Boilerplates close to this stack

Matched on React Native plus the parts of this stack our catalog tags. Each card shows which pieces actually line up, so you can see how much you would still wire yourself.

A CLAUDE.md for this stack

The rules that matter for this combination specifically, including who owns entitlement state. Adapt the commands to your repository before committing it.

CLAUDE.md
# CLAUDE.md

This project is a React Native SaaS on Supabase, Supabase Auth and RevenueCat.

## Stack

- Framework: React Native
- Database: Supabase
- Auth: Supabase Auth
- Payments: RevenueCat

## Boundaries

- Never edit a migration that has already run. Write a new one.
- Never hardcode RevenueCat price or product identifiers in components. They belong in config.
- Never trust a client-supplied user id. Read the session from Supabase Auth on the server.
- Treat webhook handlers as idempotent. The same event will arrive twice.

## Entitlements

- RevenueCat is the source of truth for what a customer paid for.
- The database mirrors that state; it never decides it.
- Any check for "can this user do X" reads the mirrored entitlement, not a live API call.

## Before you say a change is done

- The app builds.
- Tests pass.
- No secret, key or webhook signing secret appears in a committed file.

Related stacks