# Expo API Routes

Use when adding server-side API routes to an Expo Router app (+api.ts files) for...

- Repository: https://github.com/coco-research/coco (797 stars)
- Category: Data and ML
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add coco-research/coco --skill expo-api-routes -g -a claude-code -y`
Codex: `npx skills add coco-research/coco --skill expo-api-routes -g -a codex -y`
Cursor: `npx skills add coco-research/coco --skill expo-api-routes -g -a cursor -y`
Gemini CLI: `npx skills add coco-research/coco --skill expo-api-routes -g -a gemini-cli -y`

## Description

Use when adding server-side API routes to an Expo Router app (+api.ts files) for secrets, database access, third-party proxies, webhooks, CORS, or EAS Hosting deploys. Covers file routing, env vars, and Cloudflare Workers limits.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

## When to Use API Routes

Use API routes when you need:

- **Server-side secrets**, API keys, database credentials, or tokens that must never reach the client
- **Database operations**, Direct database queries that shouldn't be exposed
- **Third-party API proxies**, Hide API keys when calling external services (OpenAI, Stripe, etc.)
- **Server-side validation**, Validate data before database writes
- **Webhook endpoints**, Receive callbacks from services like Stripe or GitHub
- **Rate limiting**, Control access at the server level
- **Heavy computation**, Offload processing that would be slow on mobile

## When NOT to Use API Routes

Avoid API routes when:

- **Data is already public**, Use direct fetch to public APIs instead
- **No secrets required**, Static data or client-safe operations
- **Real-time updates needed**, Use WebSockets or services like Supabase Realtime
- **Simple CRUD**, Consider Firebase, Supabase, or Convex for managed backends
- **File uploads**, Use direct-to-storage uploads (S3 presigned URLs, Cloudflare R2)
- **Authentication only**, Use Clerk, Auth0, or Firebase Auth instead

## File Structure

API routes live in the `app` directory with `+api.ts` suffix:

```
app/
  api/
    hello+api.ts          → GET /api/hello
    users+api.ts          → /api/users
    users/[id]+api.ts     → /api/users/:id
  (tabs)/
    index.tsx
```

## Basic API Route

```ts
// app/api/hello+api.ts
export function GET(request: Request) {
  return Response.json({ message: "Hello from Expo!" });
}
```

## HTTP Methods

Export named functions for each HTTP method:

```ts
// app/api/items+api.ts
export function GET(request: Request) {
  return Response.json({ items: [] });
}

export async function POST(request: Request) {
  const body = await request.json();
  return Response.json({ created: body }, { status: 201 });
}

export async function PUT(request: Request) {
  const body = await request.json();
  return Response.json({ updated: body });
}

The rest: https://github.com/coco-research/coco/blob/HEAD/skills/expo-api-routes/SKILL.md
