We sell React Native templates. In Q1 2026 we rewrote our docs. Support tickets dropped 70%. This is the exact process, the exact structure, and the numbers.
The audit (do this first)
Before rewriting a single page, tag every support ticket for six weeks. Six columns:
date | customer | category | root_cause | resolution | in_docs?
Categories we ended up with: install, configure, extend, ship, billing, other.
Root causes: docs_missing, docs_wrong, docs_unfindable, product_bug, user_misunderstanding, out_of_scope.
The audit output for us:
| Category | % of tickets | Docs-fixable? |
|---|---|---|
| install | 24% | yes |
| configure | 21% | yes |
| extend | 18% | yes |
| ship | 5% | yes |
| billing | 10% | no |
| other | 22% | mostly no |
68% of tickets were docs-fixable. That number is the whole rest of the article.
The four-mode structure
Restructure your doc site around the four stages a new customer hits, in order:
docs/
βββ getting-started/ # install
β βββ installation.mdx
β βββ environment.mdx
β βββ quick-start.mdx
β βββ folder-structure.mdx
βββ core-concepts/ # configure
β βββ supabase.mdx
β βββ expo-integration.mdx
β βββ ui-components.mdx
βββ extend/ # extend
β βββ adding-a-screen.mdx
β βββ auth-guards.mdx
β βββ swapping-ai-provider.mdx
βββ ship/ # ship
βββ eas-build.mdx
βββ app-store.mdx
βββ ota-updates.mdx
Order matters. Doc-site ordering is not aesthetic. It is a state machine β each page assumes the customer completed the previous one.
The five rules
Print these. Stick them to a monitor.
1. First paragraph states the outcome, not the topic.
Bad:
# Authentication
This page covers authentication in the template.
Good:
# Adding auth to a new screen
By the end of this page, tapping a locked screen will redirect
signed-out users to `/sign-in` and preserve the deep link they
originally opened.
2. Every code block is copy-paste runnable.
Bad:
// ... existing imports
export function Screen() {
const { user } = useSupabase();
// ...
}
Good:
import { useSupabase } from "@/lib/supabase";
import { Redirect } from "expo-router";
export function ProtectedScreen() {
const { user, loading } = useSupabase();
if (loading) return null;
if (!user) return <Redirect href="/sign-in" />;
return <YourScreenContents />;
}
3. Every page links to the next page. Never let the customer bounce to Google.
4. If you answer the same email twice, the docs get updated that day. Same day. This is the only rule with real leverage.
5. Ship a claude.md at the project root. If your customer opens the template in Claude Code, Cursor, or any AI-native editor, the AI reads this file first. The one we ship in every Applighter template looks roughly like this:
# Applighter β <template name>
## Stack
- Expo 54, React Native 0.76
- Supabase (auth, Postgres, storage, edge functions)
- NativeWind 4, React Native Reusables (primitives)
- TanStack Query 5
## Key files
- `app/(auth)/*` β auth flows
- `app/(app)/*` β signed-in surface
- `lib/supabase.ts` β client + typed helpers
- `supabase/migrations/*` β schema (RLS policies live here)
## Conventions
- All server access via TanStack Query hooks in `hooks/`
- Never call supabase-js directly from a component
- Add new tables with a migration, not the dashboard
## Env vars
See `.env.example`.
The AI now writes correct code the first time. The customer never emails you.
Operational loop
Once the docs exist, keep them alive:
- Log every ticket in a shared sheet (6 columns above).
- 30-minute triage every Friday. Flag anything asked twice.
- Doc gap β paragraph inline or new page scaffolded same day.
That's it. No LLM classification. No analytics vendor. The marginal cost of writing one paragraph is much lower than the marginal cost of answering the same email eight times.
Results
- Support tickets: β70%
- Docs-caused refunds: β85% (from ~4% to ~0.6% of purchases)
- Time-to-first-customized-screen: 2β4 hours β 25β45 min
- Five-star reviews mentioning "docs": 2 β 34 across two quarters
What we didn't do
- No chatbot. Deflection metrics are gameable.
- No paywalled docs. Public and indexable.
- No community forum. Half-populated forums are worse than none.
- No codebase restructure to match docs. Different audiences, different shapes.
Reference docs I used
- DiΓ‘taxis framework β the closest published version of what we independently arrived at
- Expo docs β the bar for RN documentation
- Supabase docs β same
If you sell anything to developers, run the audit this week β tag your last hundred tickets and the shape of your docs problem will be obvious within an hour. Drop a comment with what your top ticket category turns out to be; curious whether install beats configure for everyone or just for us.










