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/[email protected]",
      "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 🫡