Quick Start
1. Initialize Convex
From your project root:- Create a new Convex project (or link to existing)
- Save
CONVEX_DEPLOYMENTto.env.local - Save
EXPO_PUBLIC_CONVEX_URLto.env.local - Start watching for changes
First time? You’ll be prompted to log in to Convex and create a project.
2. Set Up Authentication Keys
Convex Auth requiresJWT_PRIVATE_KEY and JWKS environment variables for signing and verifying tokens. The easiest way to set them up:
JWT_PRIVATE_KEY and JWKS automatically.
Manual setup (if CLI doesn't work)
Manual setup (if CLI doesn't work)
If you have uncommitted changes or the CLI fails, generate keys manually:Then set both values in Convex:
3. Set Backend Provider
Add toapps/app/.env:
4. Add Seed Data
5. Run Your App
Project Structure
Environment Variables
Convex uses server-side environment variables (set in Convex Dashboard) and client-side variables (in your.env file).
Required Server-Side Variables
These must be set in the Convex Dashboard → Settings → Environment Variables:
Generate and set both keys:
OAuth Provider Variables
Set these in Convex Dashboard if using social login:Client-Side Variables
These go inapps/app/.env:
Useful Commands
Authentication Setup
The boilerplate includes pre-configured auth providers inconvex/auth.ts:
Available Providers
Configure OAuth Providers
- Go to Convex Dashboard
- Select your project → Settings → Environment Variables
- Add the required credentials:
Using Auth in Your App
The useAuth() Hook
UseuseAuth() for all auth operations. It’s the ONLY auth hook you need:
useAuth() works with both Supabase and Convex - all auth methods including magic link/OTP are supported on both backends.Database Operations
Queries (Reading Data)
Mutations (Writing Data)
Security
Convex uses function-level security. Always use the security helpers inconvex/lib/security.ts:
Available Helpers
Seed Data
Commands
Demo Data Included
- 2 demo users:
demo@shipnative.app,test@shipnative.app - 3 sample posts: Published and draft examples
- Sample comments: With threading
- Welcome notifications: For each user
Realtime Features
Convex queries are reactive by default. The boilerplate also includes explicit presence and broadcast functions:Presence Tracking
Broadcast Messages
File Storage
Convex provides built-in file storage. Upload files directly to Convex and get URLs for display.Upload Files
Get File URLs
Cron Jobs
Convex supports scheduled tasks via cron jobs defined inconvex/crons.ts.
Built-in Jobs
Adding Custom Crons
Type Safety
Convex provides end-to-end type safety from your schema to your React components.How It Works
Benefits
- No manual type definitions - types are generated from your schema
- Autocomplete everywhere - IDE knows all available fields
- Catch errors early - TypeScript errors before you run the code
- Refactoring safety - rename a field and see all usages
Deployment
Development
Production
Environment Variables
Production secrets must be set in the Convex Dashboard:- Go to dashboard.convex.dev
- Select your project
- Settings → Environment Variables
- Add all OAuth credentials and API keys
Troubleshooting
”Missing environment variable JWT_PRIVATE_KEY”, “JWKS”, or “pkcs8 format” error
This means the auth keys are missing or incorrectly formatted. Run the Convex Auth setup:”Convex URL not configured” in app
Ensure.env.local has EXPO_PUBLIC_CONVEX_URL set, then restart Metro:
Auth not persisting
- Check SecureStore permissions (iOS/Android)
- Verify ConvexProvider wraps your app
- Check console for errors
Types not updating
Regenerate types:Local backend not running
OAuth not working on mobile
OAuth requires a publicly accessibleSITE_URL. If you’re using local Convex (127.0.0.1), OAuth will show “Convex Auth is running” instead of redirecting to the OAuth provider.
Next Steps
Authentication
Deep dive into auth flows
Realtime
Live updates and presence
Backend & Database
Schema and security patterns
Deploy
Ship to production

