Playground & Docs
app/index.tsx
│
├── Not authenticated ──→ auth/login.tsx ←──→ auth/signup.tsx
│ │
│ └──→ auth/adapter.tsx (change backend)
│
└── Authenticated ──→ (tabs)/_layout.tsx
├── Blog tab (index.tsx)
│ └──→ blog/create.tsx
│ └──→ blog/[id].tsx (view/edit/delete)
└── Profile tab (profile.tsx)
└──→ auth/adapter.tsx
AppProvider (context.tsx)
│
├── client ────────→ SDK client instance
├── auth ──────────→ { isAuthenticated, user }
├── adapterType ───→ 'mock' | 'supabase' | 'pocketbase'
├── switchAdapter ─→ Rebuilds client with new adapter
├── signIn / signUp → client.auth.signInWithPassword / signUp
└── signOut ───────→ client.auth.signOut
All screens access the SDK through the useApp() hook. The client is rebuilt when the adapter changes, and auth state resets.
const { data } = await client
.from('posts')
.select('*')
.order('created_at', { ascending: false });
await client.from('posts').insert({
title: 'My New Post',
content: 'Post body here...',
author_id: auth.user.id,
author_name: auth.user.email,
created_at: new Date().toISOString(),
});
await client
.from('posts')
.update({ title: 'Updated Title', content: 'New content' })
.eq('id', postId);
await client
.from('posts')
.delete()
.eq('id', postId);
await client.storage.createBucket('avatars', { public: true });
await client.storage.from('avatars').upload(fileName, imageUri);
const { data } = client.storage.from('avatars').getPublicUrl(fileName);
await client
.from('profiles')
.update({ name, bio, avatar_url: avatarUri })
.eq('id', auth.user.id);