
integrating-convex-expo
Use this skill when working on an Expo or React Native app that uses, adds, debugs, or migrates to Convex. It covers npx convex dev, EXPOPUBLICCONVEXURL and EAS envs, ConvexReactClient and provider wiring in expo-router or App.tsx, generated api imports, schema and index design, queries, mutations, actions, auth (Clerk, Convex Auth, JWT or OIDC), file uploads from Expo URIs, pagination, migrations, and common useQuery or generated failures. Do not use it for generic Expo UI or navigation work, or for non-Expo Convex frontends unless the task is specifically about adapting them to this mobile stack.
- Installs
- 74
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/tristanmanchester/agent-skills --skill integrating-convex-expo- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads integrating-convex-expo automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Integrating Convex with Expo (React Native)
Use this skill to add, repair, extend, or harden a Convex backend for an Expo app without drifting into web-only patterns or generic React Native advice.
Use this skill for
- Adding Convex to an existing Expo or Expo Router app.
- Fixing broken environment setup, provider wiring, or generated API imports.
- Building an end-to-end feature slice: schema, indexes, backend functions, frontend hooks, and validation.
- Choosing and implementing auth for Expo + Convex.
- Uploading files from Expo URIs into Convex storage.
- Refactoring for pagination, indexes, migrations, or reusable components.
- Hardening a project before preview or production release.
Do not use this skill for
- Pure Expo UI, animation, navigation, or styling work with no Convex involvement.
- Convex projects whose frontend is not Expo or React Native.
- Generic backend architecture discussions that do not need Expo-specific environment or client wiring.
Success criteria
A good outcome should leave the project with:
- A single, correctly scoped Convex client and provider.
- Working
EXPO_PUBLIC_CONVEX_URLhandling in local development and EAS. - Backend functions that match Convex best practices for validators, auth, actions, and query performance.
- Frontend hooks using generated
apireferences with clear loading, empty, and error states. - A validation pass using
scripts/validate_project.py. - A clear path for future growth: pagination, indexes, auth wrappers, migrations, and linting.
Non-negotiables
- Keep
npx convex devrunning while developing or repairing the integration. - Read the deployment URL from
process.env.EXPO_PUBLIC_CONVEX_URL. - Mirror that value into EAS environments for preview and production builds.
- Create exactly one
ConvexReactClientper app, outside render paths. - Mount the provider at the true root:
app/_layout.tsx,src/app/_layout.tsx, orApp.tsx. - In Expo and React Native, set
unsavedChangesWarning: false. - Import generated references from
convex/_generated/apirather than stringly typed names. - Treat all client-callable Convex functions as untrusted entry points.
- Add
argsvalidators to public functions, and preferreturnsvalidators as well. - Keep public wrappers thin; move repeated logic into helpers, internal functions, or custom wrappers.
- Do not use
Date.now()ornew Date()inside query logic. - Do not use Node-only APIs or third-party SDKs inside queries or mutations.
- Put external API calls, heavy compute, or Node-only libraries in
actionorinternalActionfiles; if a file starts with"use node", keep it action-only. - Avoid
.filter()and unbounded.collect()on large tables; prefer indexes plus pagination. - Await every promise.
- Prefer TypeScript strict mode and the official Convex ESLint plugin.
First-pass triage
Before making changes, inspect the project and classify the job.
1. Identify the app entrypoint
Check for:
app/_layout.tsxorsrc/app/_layout.tsxfor Expo Router.App.tsxorApp.jsxfor classic entrypoints.
2. Audit Convex state
Look for:
package.jsondependencies:convex,expo, auth libraries, ESLint tooling.convex/andconvex/_generated/..env.local,.env,.env.development,.env.production.eas.jsonif cloud builds matter.- Existing provider usage:
ConvexProvider,ConvexProviderWithClerk, or custom auth wrappers. - Existing schema and indexes in
convex/schema.ts. - Existing public functions with missing validators, auth checks, or pagination.
3. Run the validator
From the project root:
python scripts/validate_project.py --root <project-root>
Use --json for machine-readable output or --fail-on-warning when you want stricter gating.
4. Choose the workflow
- Bootstrap / repair baseline: missing Convex setup, env vars, provider, or generated API.
- Build a feature slice: add backend data and UI together.
- Auth: add or repair sign-in and backend authorization.
- File uploads: move media or documents from device URIs into Convex storage.
- Scale / harden: indexes, pagination, components, linting, production checklist.
- Migration: reshape existing tables or gradually move from another backend.
Workflow A — Bootstrap or repair the baseline integration
Step 1: Install or confirm the client package
npx expo install convex
Step 2: Create or reconnect the Convex project
npx convex dev
Expect this to:
- create or connect a Convex project,
- create
convex/if missing, - generate
convex/_generated/, - write
EXPO_PUBLIC_CONVEX_URLto.env.local, - and keep syncing while the command runs.
Step 3: Ensure the root provider exists
For Expo Router:
import { ConvexProvider, ConvexReactClient } from "convex/react";
import { Stack } from "expo-router";
const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL!, {
unsavedChangesWarning: false,
});
export default function RootLayout() {
return (
<ConvexProvider client={convex}>
<Stack />
</ConvexProvider>
);
}
For classic App.tsx, wrap the top-level navigation tree the same way.
Step 4: Confirm generated imports
Use:
import { api } from "../convex/_generated/api";
or the correct relative path for the project layout. Do not hand-write function names.
Step 5: Verify development and build environments
Read references/eas-env.md and ensure the same deployment URL policy is reflected in EAS.
Step 6: Validate and smoke-test
- Start the Expo app.
- Confirm
useQuery(...)moves fromundefinedto real data. - Run
python scripts/validate_project.py --root <project-root>. - If needed, scaffold the canonical example with
python scripts/scaffold_tasks_example.py --root <project-root>.
Workflow B — Build a feature slice end to end
Build each feature in the order below.
1. Model the access pattern first
Before touching code, answer:
- Is the data public, user-scoped, org-scoped, or admin-only?
- Will the list stay small, or should it paginate?
- Which fields are lookup keys and therefore need indexes?
- Does any step require an external API, AI SDK, Stripe, or Node API?
2. Design the schema
Add or extend convex/schema.ts before the function layer whenever the model is stabilising.
Use references/schema-and-indexes.md for:
- flat relational modelling,
- foreign-key indexing,
- compound indexes around actual query shapes,
- bounded array guidance,
- and pagination thresholds.
3. Implement backend functions
Use references/functions.md for the detailed patterns.
Default rules:
queryfor deterministic reads.mutationfor writes.actionorinternalActionfor external APIs, third-party SDKs, or Node-only code.internalQueryorinternalMutationfor logic that should never be callable from the client.
4. Enforce access on the backend
If the feature is not public, do one of these:
- explicit
ctx.auth.getUserIdentity()checks in each function, or - reusable custom wrappers via
convex-helpers.
See references/auth.md and references/components-and-helpers.md.
5. Wire the frontend
Use references/frontend-patterns.md.
Always handle:
- loading:
useQuery(...) === undefined, - empty state,
- mutation pending state where relevant,
- recoverable errors,
- and pagination for unbounded lists.
6. Validate the slice
Before finishing:
- run the validator with the project root,
- run lint and typecheck if the project has them,
- verify the feature on device or simulator,
- and update or add indexes before shipping.
Workflow C — Authentication and authorization
Pick one auth story and keep the stack coherent.
Option 1: Clerk
Good when the app already uses Clerk or wants a polished auth product.
Option 2: Convex Auth
Good when you want a Convex-native auth stack and are comfortable adopting a beta library.
Option 3: Existing JWT or OIDC provider
Good when the product already depends on Auth0, WorkOS, a company IdP, or another OIDC flow.
Rules regardless of provider
- Backend authorization is mandatory; client-side gating is only for UX.
- If you persist users in Convex, index by a stable identifier such as
tokenIdentifier. - Check ownership, organisation membership, or role on every protected function.
- Prefer helper functions or custom wrappers instead of repeating auth boilerplate.
- Use internal functions for privileged internal-only operations.
Read references/auth.md for a decision matrix and implementation patterns.
Workflow D — File uploads from Expo
Use Convex upload URLs rather than trying to push raw files through a mutation.
Recommended flow:
- public or protected mutation returns
ctx.storage.generateUploadUrl(), - client loads the local
file://URI withfetch(uri)and converts it to aBlob, - client
POSTs the blob to the upload URL, - second mutation stores the returned
storageIdplus app-specific metadata, - optional scheduled or action-based post-processing happens afterwards.
Read references/file-uploads.md.
Workflow E — Scale and harden
Once the baseline works, raise the quality bar.
Performance
- Replace
.filter()scans with indexed queries where possible. - Replace unbounded
.collect()withtake,first, or paginated queries. - Use
usePaginatedQueryfor growing feeds, notifications, and infinite-scroll screens. - Push repeated or reusable feature areas into Convex components when boundaries are clear.
Safety
- Add validators consistently.
- Keep privileged logic behind internal functions.
- Use
ConvexErroror clear return shapes for expected failures. - Never trust IDs from the client without checking ownership or membership.
Maintainability
- Turn on
@convex-dev/eslint-plugin. - Use TypeScript strict mode.
- Keep wrappers thin and move shared logic into plain TypeScript helpers.
- Separate
"use node"action files from regular runtime files.
Read references/production-checklist.md.
Workflow F — Migrations
When changing a live schema, prefer additive transitions.
Default migration strategy:
- add new fields or tables in a backwards-compatible way,
- dual-read or dual-write if the shape is changing,
- backfill existing documents in idempotent batches,
- switch readers and writers,
- then remove the old shape.
Use internal functions or scheduled jobs for backfills, and keep migrations restart-safe.
Read references/migrations.md.
Fast troubleshooting path
If the app is broken, check these in order:
- Is
npx convex devrunning and free of TypeScript errors? - Does
.env.localcontainEXPO_PUBLIC_CONVEX_URL? - Was Metro restarted after the env file changed?
- Is there exactly one
ConvexReactClient? - Is the provider mounted at the real root?
- Does
convex/_generated/apiexist, and are imports pointing at it correctly? - Are public functions missing
argsorreturnsvalidators? - Is a query using
Date.now(),.filter(), or unbounded.collect()? - Is a
"use node"file incorrectly mixing queries or mutations? - Is auth mismatched between the client provider and the backend config?
See references/troubleshooting.md.
Available scripts
-
scripts/validate_project.py- Validates the project rooted at
--rootor, if copied into a repo, the current working tree. - Validates Expo and Convex dependencies.
- Checks env files, provider wiring, generated code, validator presence,
"use node"misuse, and common query anti-patterns. - Supports
--json,--root, and--fail-on-warning.
- Validates the project rooted at
-
scripts/scaffold_tasks_example.py- Dry-run by default.
- Can generate
sampleData.jsonl,convex/schema.ts,convex/tasks.ts, and an optional Expo screen file. - Supports
--write,--overwrite,--ui-file, and--json.
References
Load only the file that matches the current task.
- references/eas-env.md — local envs, EAS envs, and deployment URL handling.
- references/tasks-example.md — canonical minimal example for the stack.
- references/schema-and-indexes.md — schema design, indexes, query shape mapping, and pagination triggers.
- references/functions.md — query, mutation, action, internal function, validators, and runtime boundaries.
- references/frontend-patterns.md — provider placement, hook usage, loading and error states, and paginated lists.
- references/auth.md — Clerk, Convex Auth, JWT or OIDC, user mapping, and server-side authorization.
- references/file-uploads.md — upload URLs, Expo URI handling, metadata storage, and post-processing.
- references/components-and-helpers.md — Convex components and
convex-helperspatterns. - references/migrations.md — additive rollout, backfills, dual reads and writes, and batched migrations.
- references/production-checklist.md — pre-release hardening checklist.
- references/troubleshooting.md — common failures and exact fixes.
- references/evaluation.md — how to use the bundled trigger and output eval files.
- references/sources.md — upstream docs and materials used for this rewrite.
FAQ
What does the integrating-convex-expo skill do?
Use this skill when working on an Expo or React Native app that uses, adds, debugs, or migrates to Convex. It covers npx convex dev, EXPOPUBLICCONVEXURL and EAS envs, ConvexReactClient and provider wiring in expo-router or App.tsx, generated api imports, schema and index design, queries, mutations, actions, auth (Clerk, Convex Auth, JWT or OIDC), file uploads from Expo URIs, pagination, migrations, and common useQuery or generated failures. Do not use it for generic Expo UI or navigation work, or for non-Expo Convex frontends unless the task is specifically about adapting them to this mobile stack.
How do I install integrating-convex-expo?
Run npx skills add https://github.com/tristanmanchester/agent-skills --skill integrating-convex-expo in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/integrating-convex-expo/ (personal) or .claude/skills/integrating-convex-expo/ (project).
Which AI agents can use integrating-convex-expo?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is integrating-convex-expo safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains integrating-convex-expo?
It is published by tristanmanchester in tristanmanchester/agent-skills. It has 74 recorded installs.
More from tristanmanchester/agent-skills
designing-beautiful-websites
tristanmanchester/agent-skills
Design, implement, or critique website and web-app UX/UI: information structure, user flows, responsive layouts, visual systems, content, and interaction states. Use for a requested interface or visual-design change; do not expand a small component edit into an unrequested product redesign.
reddit-readonly
tristanmanchester/agent-skills
Browse and search Reddit in read-only mode using public JSON endpoints. Use when the user asks to browse subreddits, search for posts by topic, inspect comment threads, or build a shortlist of links to review and reply to manually.
animating-react-native-expo
tristanmanchester/agent-skills
Implement and debug React Native or Expo motion with Reanimated 4 and Gesture Handler 3: state transitions, layout, gestures, scroll, worklets, cancellation, and accessible alternatives. Use for native UI motion, not web Motion or a reason to add canvas graphics to ordinary views.
styling-nativewind-v4-expo
tristanmanchester/agent-skills
Set up, repair, and build components with NativeWind v4 and Tailwind CSS v3 in Expo React Native apps. Use for an explicitly v4 project, v4 configuration failures, className interoperability, or v4 theming; not for NativeWind v5 or generic web Tailwind setup.
nextjs-framer-motion-animations
tristanmanchester/agent-skills
Implement and debug Motion for React in Next.js: local interaction, presence, layout, shared elements, scroll, reduced motion, and router integration. Use for explicit Motion/Framer Motion work or interactions that need it; prefer CSS for simple effects and framework-native view transitions for supported route cases.
react-native-skia
tristanmanchester/agent-skills
Build, debug, or profile React Native Skia canvases, paths, rich text, shaders, images, snapshots, video, and animated graphics. Use when Skia is selected or custom drawing is needed. Do not introduce a canvas merely because ordinary native UI should look polished or animate smoothly.
Popular mobile skills
design-mobile-apps
designed-by-ai/skills
Design mobile app screens with Sleek, edit Sleek projects, and implement their designs in React Native or HTML.
ios-design
uizze.sh
Design and review iOS UI/UX for iPhone apps in SwiftUI, UIKit, or React Native. Use for mobile app design, screen redesigns, navigation flows, typography, forms, keyboard and safe-area layout, and accessibility checks. Apply Apple Human Interface Guidelines and consult real product references through the optional Uizze connection.
vercel-react-native-skills
vercel-labs/agent-skills
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
animate-expo
emilkowalski/skills
Build animations in React Native and Expo, making the decisions in the order that determines whether they feel right — should it animate, which thread it runs on, which properties, spring or timing, how the gesture hands off, how it degrades. Writes the implementation with Reanimated, Gesture Handler, Expo Router and expo-haptics. Use when animating anything in an Expo app, adding gestures, sheets, screen transitions, press feedback or haptics, or fixing motion that stutters on device. For web animation use animate.
xcode-project-setup
firebase/agent-skills
Safely modifies Xcode projects (.pbxproj) to add Swift Packages and link files. Use this skill whenever an iOS project needs dependencies installed (e.g. Firebase, Alamofire).
firebase-remote-config-basics
firebase/agent-skills
Manages Firebase Remote Config templates, feature flags, loading strategies, and SDKs (Android, iOS). Use when downloading/deploying remoteconfig JSON templates, managing version history/feature flags, setting in-app defaults, fetchAndActivate(), real-time listeners, or SDK setup. Don't use for Firebase Hosting, Auth, Firestore, Data Connect, Crashlytics, or App Hosting.