Hosting Expo SPAs and APIs on Vercel: Up to date and tested.
Note: The official Expo guide (Expo: Publishing Websites) didn't work for me. Here's the setup that actually worked when deploying an Expo SPA with API routes to Vercel.
3 Things to Remember
- vercel.json → deployment config
- api/index.ts → entry for production
- app.json → ensure correct web output
vercel.json
{
  "buildCommand": "expo export -p web",
  "outputDirectory": "dist/client",
  "devCommand": "expo",
  "cleanUrls": true,
  "framework": null,
  "functions": {
    "api/index.ts": {
      "runtime": "@vercel/node@5.1.8",
      "includeFiles": "dist/server/**"
    }
  },
  "rewrites": [{ "source": "/(.*)", "destination": "/api/index" }]
}
api/index.ts
You will create this in the project root.
Remember this is so the server can serve the app on Vercel, not where your actual API routes live during development.
const { createRequestHandler } = require("@expo/server/adapter/vercel");
module.exports = createRequestHandler({
  build: require("path").join(__dirname, "../dist/server"),
});
app.json
{
  "web": {
    "bundler": "metro",
    "output": "server",
    "favicon": "./assets/images/favicon.png"
  },
  "assetBundlePatterns": ["**/*"]
}
Deploy
vercel deploy
✅ That's it. SPA + API running on Vercel with Expo's server output.
Happy Shipping 🫡
