Eas Hosting
expo/skills
Deploy Expo websites and Expo Router API routes to EAS Hosting - export the web bundle, run eas deploy for production and PR preview URLs, manage environment secrets and custom domains, and work…
Guidelines for creating API routes in Expo Router with EAS Hosting
$ npx skills add adrianhajdin/react-native-lingua --skill expo-api-routes -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install adrianhajdin/react-native-lingua expo-api-routes --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/adrianhajdin/react-native-lingua.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/expo-api-routes .claude/skills/expo-api-routes && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "expo-api-routes" agent skill from https://github.com/adrianhajdin/react-native-lingua/tree/main/.agents/skills/expo-api-routes into .claude/skills/expo-api-routes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "expo-api-routes", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/adrianhajdin/react-native-lingua/tree/main/.agents/skills/expo-api-routesType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add adrianhajdin/react-native-lingua --skill expo-api-routes -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install adrianhajdin/react-native-lingua expo-api-routes --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/adrianhajdin/react-native-lingua.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/expo-api-routes .agents/skills/expo-api-routes && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "expo-api-routes" agent skill from https://github.com/adrianhajdin/react-native-lingua/tree/main/.agents/skills/expo-api-routes into .agents/skills/expo-api-routes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "expo-api-routes", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add adrianhajdin/react-native-lingua --skill expo-api-routes -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install adrianhajdin/react-native-lingua expo-api-routes --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/adrianhajdin/react-native-lingua.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/expo-api-routes .cursor/skills/expo-api-routes && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "expo-api-routes" agent skill from https://github.com/adrianhajdin/react-native-lingua/tree/main/.agents/skills/expo-api-routes into .cursor/skills/expo-api-routes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "expo-api-routes", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/adrianhajdin/react-native-lingua.git --path .agents/skills/expo-api-routes--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add adrianhajdin/react-native-lingua --skill expo-api-routes -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install adrianhajdin/react-native-lingua expo-api-routes --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/adrianhajdin/react-native-lingua.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/expo-api-routes .gemini/skills/expo-api-routes && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "expo-api-routes" agent skill from https://github.com/adrianhajdin/react-native-lingua/tree/main/.agents/skills/expo-api-routes into .gemini/skills/expo-api-routes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "expo-api-routes", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install adrianhajdin/react-native-lingua expo-api-routesInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add adrianhajdin/react-native-lingua --skill expo-api-routes -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/adrianhajdin/react-native-lingua.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/expo-api-routes .github/skills/expo-api-routes && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "expo-api-routes" agent skill from https://github.com/adrianhajdin/react-native-lingua/tree/main/.agents/skills/expo-api-routes into .github/skills/expo-api-routes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "expo-api-routes", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add adrianhajdin/react-native-lingua --skill expo-api-routes -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install adrianhajdin/react-native-lingua expo-api-routes --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/adrianhajdin/react-native-lingua.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/expo-api-routes .opencode/skills/expo-api-routes && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "expo-api-routes" agent skill from https://github.com/adrianhajdin/react-native-lingua/tree/main/.agents/skills/expo-api-routes into .opencode/skills/expo-api-routes/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "expo-api-routes", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
expo-api-routesGuidelines for creating API routes in Expo Router with EAS Hosting
Expo API Routes is an agent skill from adrianhajdin/react-native-lingua. Guidelines for creating API routes in Expo Router with EAS Hosting
Its SKILL.md is about 2.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Mobile, covering Cross-platform mobile apps. It works with Expo and Cloudflare Workers. The repository describes itself as: React Native Duolingo clone with a real-time AI voice teacher. Built with Expo, Stream Voice Agents, Clerk auth, and NativeWind for a complete, interactive mobile learning… The licence is MIT.
Read from SKILL.md and the folder at commit 7ddc202. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
eascurlnpxnpmFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
api.openai.comapi.weather.comFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
OPENAI_API_KEYTURSO_AUTH_TOKENWEATHER_API_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Expo API Routes loads about 2.2k tokens when it runs. Until then it costs about 21 tokens; SKILL.md has 423 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
- **Local**: Create `.env` file (never commit)Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from adrianhajdin/react-native-lingua at commit 7ddc202, republished under its MIT licence (© adrianhajdin). 423 words, ~2,163 tokens.
.claude/skills/expo-api-routes/SKILL.md (or your agent's skills folder).Use API routes when you need:
Avoid API routes when:
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// app/api/hello+api.ts
export function GET(request: Request) {
return Response.json({ message: "Hello from Expo!" });
}Export named functions for each HTTP method:
// 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 });
}
export async function DELETE(request: Request) {
return new Response(null, { status: 204 });
}// app/api/users/[id]+api.ts
export function GET(request: Request, { id }: { id: string }) {
return Response.json({ userId: id });
}export function GET(request: Request) {
const url = new URL(request.url);
const page = url.searchParams.get("page") ?? "1";
const limit = url.searchParams.get("limit") ?? "10";
return Response.json({ page, limit });
}export function GET(request: Request) {
const auth = request.headers.get("Authorization");
if (!auth) {
return Response.json({ error: "Unauthorized" }, { status: 401 });
}
return Response.json({ authenticated: true });
}export async function POST(request: Request) {
const { email, password } = await request.json();
if (!email || !password) {
return Response.json({ error: "Missing fields" }, { status: 400 });
}
return Response.json({ success: true });
}Use process.env for server-side secrets:
// app/api/ai+api.ts
export async function POST(request: Request) {
const { prompt } = await request.json();
const response = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
},
body: JSON.stringify({
model: "gpt-4",
messages: [{ role: "user", content: prompt }],
}),
});
const data = await response.json();
return Response.json(data);
}Set environment variables:
.env file (never commit)eas env:create or Expo dashboardAdd CORS for web clients:
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
};
export function OPTIONS() {
return new Response(null, { headers: corsHeaders });
}
export function GET() {
return Response.json({ data: "value" }, { headers: corsHeaders });
}export async function POST(request: Request) {
try {
const body = await request.json();
// Process...
return Response.json({ success: true });
} catch (error) {
console.error("API error:", error);
return Response.json({ error: "Internal server error" }, { status: 500 });
}
}Start the development server with API routes:
npx expo serveThis starts a local server at http://localhost:8081 with full API route support.
Test with curl:
curl http://localhost:8081/api/hello
curl -X POST http://localhost:8081/api/users -H "Content-Type: application/json" -d '{"name":"Test"}'npm install -g eas-cli
eas logineas deployThis builds and deploys your API routes to EAS Hosting (Cloudflare Workers).
# Create a secret
eas env:create --name OPENAI_API_KEY --value sk-xxx --environment production
# Or use the Expo dashboardConfigure in eas.json or Expo dashboard.
API routes run on Cloudflare Workers. Key limitations:
fs module unavailable// Use Web Crypto instead of Node crypto
const hash = await crypto.subtle.digest(
"SHA-256",
new TextEncoder().encode("data")
);
// Use fetch instead of node-fetch
const response = await fetch("https://api.example.com");
// Use Response/Request (already available)
return new Response(JSON.stringify(data), {
headers: { "Content-Type": "application/json" },
});Since filesystem is unavailable, use cloud databases:
Example with Turso:
// app/api/users+api.ts
import { createClient } from "@libsql/client/web";
const db = createClient({
url: process.env.TURSO_URL!,
authToken: process.env.TURSO_AUTH_TOKEN!,
});
export async function GET() {
const result = await db.execute("SELECT * FROM users");
return Response.json(result.rows);
}// From React Native components
const response = await fetch("/api/hello");
const data = await response.json();
// With body
const response = await fetch("/api/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "John" }),
});// utils/auth.ts
export async function requireAuth(request: Request) {
const token = request.headers.get("Authorization")?.replace("Bearer ", "");
if (!token) {
throw new Response(JSON.stringify({ error: "Unauthorized" }), {
status: 401,
headers: { "Content-Type": "application/json" },
});
}
// Verify token...
return { userId: "123" };
}
// app/api/protected+api.ts
import { requireAuth } from "../../utils/auth";
export async function GET(request: Request) {
const { userId } = await requireAuth(request);
return Response.json({ userId });
}// app/api/weather+api.ts
export async function GET(request: Request) {
const url = new URL(request.url);
const city = url.searchParams.get("city");
const response = await fetch(
`https://api.weather.com/v1/current?city=${city}&key=${process.env.WEATHER_API_KEY}`
);
return Response.json(await response.json());
}© adrianhajdin, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/expo-api-routes of adrianhajdin/react-native-lingua.
Open the folder on GitHubat commit 7ddc202
We found 21 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 6 other GitHub owners. This page covers the copy in adrianhajdin/react-native-lingua, which our catalogue first saw on October 7, 2026.
Expo API Routes next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Expo API Routes this skilladrianhajdin/react-native-lingua | 152 | 6 repos | ~2.2k | Automated safety check: Notes | MIT | |
| Eas Hostingexpo/skills | 2.7k | 2 repos | ~2.9k | Automated safety check: Notes | MIT | |
| React Native Best Practicesvercel-labs/openreview | 1.7k | 17 repos | ~1.1k | Automated safety check: Pass | MIT | |
| Expo Cicd WorkflowsCherryHQ/cherry-studio-app | 4k | 6 repos | ~870 | Automated safety check: Pass | MIT | |
| Expo Modulebbplayer-app/BBPlayer | 1.2k | 3 repos | ~1.4k | Automated safety check: Pass | MIT | |
| Appllama App Design SkillAppllama/appllama-skills | 2.5k | 1 repos | ~5k | Automated safety check: Pass | MIT |
expo/skills
Deploy Expo websites and Expo Router API routes to EAS Hosting - export the web bundle, run eas deploy for production and PR preview URLs, manage environment secrets and custom domains, and work…
vercel-labs/openreview
A prioritized rule set for React Native and Expo apps covering list performance, animation, navigation, UI patterns, state, rendering, monorepos and configuration.
CherryHQ/cherry-studio-app
Helps understand and write EAS workflow YAML files for Expo projects.
bbplayer-app/BBPlayer
Guide for creating and writing Expo native modules and views using the Expo Modules API (Swift, Kotlin, TypeScript).
Appllama/appllama-skills
Build native-feeling, benchmark-quality mobile app screens (Expo / React Native).
CherryHQ/cherry-studio-app
Complete guide for building beautiful apps with Expo Router.
adrianhajdin/react-native-lingua
Expo / React Native patterns with Clerk — SecureStore token cache, OAuth deep linking, useAuth in native, Expo Router protected routes, push notifications with user context.
adrianhajdin/react-native-lingua
Create, build, and integrate Stream Chat React Native apps in React Native Community CLI and Expo.
adrianhajdin/react-native-lingua
Build a new app or add Stream products (Chat, Video, Feeds, Moderation) to an existing app.
adrianhajdin/react-native-lingua
Query Stream data and run CLI operations against Chat, Video, Feeds, and Moderation: list channels, list calls, show flagged messages, find users, query any Stream resource.
adrianhajdin/react-native-lingua
Search live Stream SDK documentation for Chat, Video, Feeds, and Moderation.
adrianhajdin/react-native-lingua
Stream router for Chat, Video, Feeds, and Moderation. An agent skill from adrianhajdin/react-native-lingua.
Works with
Categories
Guidelines for creating API routes in Expo Router with EAS Hosting. Expo API Routes is an agent skill from adrianhajdin/react-native-lingua.
Expo API Routes fits situations like: tasks that involve Cross-platform mobile apps.
Run `npx skills add adrianhajdin/react-native-lingua --skill expo-api-routes -a claude-code`. Or copy the skill folder (.agents/skills/expo-api-routes in adrianhajdin/react-native-lingua) into .claude/skills/expo-api-routes in your project. Claude Code loads it when a task matches its description.
Run `npx skills add adrianhajdin/react-native-lingua --skill expo-api-routes -a codex`. Or copy the skill folder (.agents/skills/expo-api-routes in adrianhajdin/react-native-lingua) into .agents/skills/expo-api-routes in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add adrianhajdin/react-native-lingua --skill expo-api-routes -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/expo-api-routes, .gemini/skills/expo-api-routes, .github/skills/expo-api-routes and .opencode/skills/expo-api-routes in your project.
Going by SKILL.md and its folder, Expo API Routes needs the command-line tools its instructions call (eas, curl, npx and npm) and credentials named OPENAI_API_KEY, TURSO_AUTH_TOKEN and WEATHER_API_KEY. Our summary lists: Node.js; A credential in OPENAI_API_KEY; A credential in TURSO_AUTH_TOKEN.
SKILL.md names 2 domains. In commands or code: api.openai.com and api.weather.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Expo API Routes is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.2k tokens (SKILL.md is roughly 8.7k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Expo API Routes: Eas Hosting (expo/skills, 2.7k stars), React Native Best Practices (vercel-labs/openreview, 1.7k stars), Expo Cicd Workflows (CherryHQ/cherry-studio-app, 4k stars) and Expo Module (bbplayer-app/BBPlayer, 1.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
adrianhajdin (a GitHub user) maintains it in adrianhajdin/react-native-lingua, which has 152 GitHub stars. The repository holds 7 skills in this directory. The repository was last updated on May 15, 2026.
Source: adrianhajdin/react-native-lingua on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.