Note: This is the honest developer-story version of an internal postmortem. If you want a shorter, more meme-friendly version, we have one on Medium. If you want a first, code-heavy version, it's on Dev.to. This one is the long form.
Where we started
Two founders. 180 combined hours of work. One React Native template we were quietly proud of. Twelve screens, Expo SDK, TypeScript, NativeWind, tab-based navigation, auth screens that looked like Instagram's. We priced it at $29 and launched on a Tuesday morning.
By Friday evening we had:
- 5 sales
- 4 refund requests
- 1 chargeback in flight
- $87 in the bank
- 1 email from a customer named "Dev" (probably not his real name) that started with "Hey guys, I have to be honest with you..."
That email is where this post starts.
The email that changed the company
The paraphrased version:
I thought this was going to save me a week. It saved me maybe an evening. The auth doesn't connect to anything, the API returns hardcoded data, and I still have to build the entire backend. Why did I pay $29 for what's basically a Figma export in TypeScript?
Every sentence was honest. We had shipped a UI kit. Our landing page used the phrase "full-stack" four times. In the repo, "full-stack" meant this:
// src/services/mockApi.ts
export const HARDCODED_NOTES: Note[] = [
{ id: '1', title: 'Meeting notes', body: '...' },
{ id: '2', title: 'Idea', body: '...' },
];
export async function getNotes(): Promise<Note[]> {
await sleep(300); // for that "loading" feel
return HARDCODED_NOTES;
}
The auth screens looked professional and did nothing. The Supabase env vars were placeholders. We had, to be blunt, defrauded the word "full-stack."
The audit
Before rebuilding, we forced ourselves to write down every layer where v1 fell short of the promise on the landing page.
| Layer | Landing page promise | v1 reality |
|---|---|---|
| Database | "Postgres schema, migrations, seed data" | Zero SQL files |
| Auth | "Supabase Auth with email + OAuth" | UI screens returning fake sessions |
| Storage | "File uploads with signed URLs" | localStorage |
| AI | "OpenAI + Anthropic integration" | Not present |
| RLS | "Row-level security policies" | Not present |
| Docs | "Complete setup guide" | 800-word README |
| Demo | "See it in action" | Six screenshots |
The audit was demoralizing. It was also the roadmap.
The rebuild, layer by layer
Layer 1: real Postgres schema
Every current template ships with a supabase/migrations/ folder containing the actual tables the app needs, not a hand-wavy ER diagram. Buyers can run supabase db push and have a working schema before they've written a single line of code.
-- supabase/migrations/00_notes.sql
create table notes (
id uuid primary key default gen_random_uuid(),
user_id uuid not null references auth.users on delete cascade,
title text not null,
body text,
created_at timestamptz default now()
);
alter table notes enable row level security;
create policy "Users read their own notes"
on notes for select
using (auth.uid() = user_id);
Layer 2: auth that actually authenticates
Email, Apple, and Google via Supabase Auth, with session hooks that persist across app restarts and refresh silently. The auth screens no longer lie.
Layer 3: storage with signed URLs and RLS
For templates like Chat with PDF, file uploads go straight to Supabase Storage with a signed URL flow and per-user RLS. No customer support ticket has ever said "the file upload doesn't work."
Layer 4: real AI service layer
An Edge Function proxies OpenAI, Anthropic, or ElevenLabs calls using the buyer's own API keys. It's modular: swap GPT-4o for Claude by changing a config constant. No vendor lock-in.
Layer 5: RLS policies from day one
Every template ships with per-table policies and two seed users so buyers can immediately verify that user A cannot see user B's data. This is table-stakes for production apps, and yet somehow rare in the template market.
Layer 6: 12,000-word docs, plus video
The single highest-leverage rebuild task. Written as copy-pasteable step lists with expected output. If a step is ambiguous, it gets rewritten.
Layer 7: agent-readiness
The one most competitors still ignore. Every template ships with:
- A root
CLAUDE.mddescribing the codebase in agent-friendly terms - Slash commands and skills for the common workflows (
/add-screen,/add-supabase-table,/swap-ai-provider) - Real TypeScript types across the board (no
any) - A file layout an agent can grep in one pass
It's tested against Claude Code, Codex, Cursor, OpenCode, and Windsurf, because in 2026 the buyer's first interaction with your codebase is via an agent.
Pricing: from $29 to $79
Counterintuitive lesson: raising the price improved every downstream metric.
At $29, we attracted price-shopping buyers whose expectations were "this must also do my dishes." Refund rate was around 40%.
At $79, we attracted senior indies who value their own hour at $100+ and are buying back time. Refund rate dropped to around 4%.
The right customer for a React Native template is not price-sensitive. They are time-sensitive. Price signals seriousness.
The demo video, in detail
40 seconds. Silent. One take. This is the shot list:
- Terminal shows
git clone, thennpx expo start - iOS Simulator boots
- Sign up as a new user
- Do the hero action (record voice note, upload PDF, whatever the app does)
- Cut to the Supabase table view showing the row that just landed
- Fade out on the app logo
Nothing else. No music. No voiceover. The point is to remove doubt, not to entertain.
v1 vs v2 vs building from scratch
| v1 ($29) | v2 ($79) | From scratch | |
|---|---|---|---|
| Setup time | ~2 hours | ~30 minutes | 3–6 weeks |
| Backend | Mocked JSON | Real Supabase | You build it |
| RLS | None | Per-table + seed users | You write it |
| Demo | Screenshots | 40-sec video | N/A |
| Agent-ready | None | Skills + slash commands | You configure |
| Docs | 800 words | ~12,000 words + video | N/A |
| Refund rate | ~40% | ~4% | N/A |
For comparison, competitor templates like Ignite Cookbook ship strong scaffolding but leave the backend and AI as reader exercises. In 2026 that's the wrong tradeoff.
The cost of getting it wrong
- 180 hours on v1 that no one wanted
- $600 in ads that returned nothing
- 200 hours on the rebuild
- ~$40k in real engineering opportunity cost
- Six months of momentum
The postmortem was expensive. This blog post is us trying to make it slightly cheaper for the next founder considering a React Native template.
What I'd tell 2025-me
- Docs first. If they're hard to write, the product is wrong.
- $79 minimum. Cheaper attracts refund-prone buyers.
- Real backend day one. Mock nothing a reasonable buyer expects to be real.
- One demo video per template. 40 seconds. Silent. Happy path.
-
Ship for agents.
CLAUDE.md, slash commands, real types. - Refund policy above the buy button. In big text.
The gap between "nice UI in a week" and "template a senior indie pays $79 for" is roughly three months of unglamorous infrastructure. Skip any of it and the launch dies quietly.
You can see where all of this ended up at Applighter.
Top comments (0)