EAS Hosting is a faster, simpler way to deploy your app and API together

ProductDevelopment7 minutes read

Phil Pluckthun

Phil Pluckthun

Engineering

EAS Hosting lets you deploy full-stack Expo apps with ease. Explore new features like expo-server, middleware support, and improved Cloudflare integration.

EAS Hosting is a faster, simpler way to deploy your app and API together

Earlier this year, we shipped EAS Hosting, our take on making it easy for shipping Expo apps for the Web and API endpoints with Expo Router.

We believe that EAS Hosting is the most streamlined way to connect your Expo apps to API endpoints and the Web and deliver apps with real functionality from day one, without having to worry about deployments.

To this end, we were aiming from the start for EAS Hosting to have all basic functionality that is required for you to monitor your API and be confident in what you’re deploying:

  • Granular request logging that integrates with the Console API and tracks your log messages, both in preview deployments and at scale for production deployments
  • Grouped crash reports for when your API routes run into uncaught errors
  • Extensive platform-grouped metrics, to give you insights into how your API routes perform and how endpoints are called

Since releasing EAS Hosting, we’ve also built services of our own with it. Expo Launch was built entirely with Expo, EAS Hosting, and EAS Workflows.

But we’re just getting started and are working towards changes and features that will gradually make EAS Hosting an obvious choice to add to any Expo project.

The expo-server runtime API

In Expo SDK 54, we’ve introduced the expo-server library. This library provides essential APIs for functionality that previously wasn’t available in API routes before.

Code
import { StatusError, deferTask, origin, environment } from 'expo-server';
export async function GET(request: Request, { post }: Record<string, string>) {
if (!post) {
throw new StatusError(404, 'No post found');
}
if (post === 'index') {
const target = new URL('/help', origin() ?? request.url);
throw Response.redirect(target, 302);
}
deferTask(async () => {
logAnalyticsDatapoint(...);
});
const env = environment();
return Response.json({ isStaging: env === 'staging' });
}

Task Scheduling APIs are not standardized in the Fetch or Web APIs that you may be used to. While many runtimes have APIs such as ctx.waitUntil(promise) available to them, expo-server provides two easy functions for task schedulings that you can call anywhere within your server-side code.

Patterns like origin(), environment() , and being able to throw a StatusError response within any part of your server-side code is functionality that we also missed while building Expo Launch on EAS Hosting.

expo-server replaces the @expo/server package and hence contains adapters for other server runtimes and providers than just EAS Hosting. We’re committed to unifying functionality between runtimes and providers and make sure that you never feel that your API route or server code in your Expo apps feels locked-in.

Learn more about expo-server's API on our API Routes docs page.

Expo Router middleware

Expo Router not having support for middleware was a larger restriction and prevented many creative ways of using API routes previously.

In Expo SDK 54, we added experimental support for middleware.

Middleware, are functions that run before other server-side code in Expo Router runs, and can hence be combined with the expo-server API. For example, you can write a middleware that customises the Response headers for every API route.

Code
import { setResponseHeaders } from 'expo-server';
export default function middleware(request: Request) {
// Append cookie to future response
setResponseHeaders(headers => {
headers.append('Set-Cookie', 'token=123; Secure');
});
}

Headers app.json configuration on EAS Hosting

We also realized that there’s configuration that both affects Expo Router and EAS Hosting simultaneously in rare cases. One example of this are default headers.

Code
{
"expo": {
"plugins": [
[
"expo-router",
{
"headers": {
"Content-Security-Policy": "frame-ancestors deny",
"Set-Cookie": ["token=123; Secure"]
}
}
]
]
}
}

With the headers configuration, a settings file is created when you export an Expo Router app that EAS Hosting picks up.

Cloudflare workerd runtime improvements

EAS Hosting is built on Cloudflare Workers and global by default. The workerd runtime that Cloudflare has built complies to WinterTC and Web API standards. However, this also means that it has restrictions that we previously tried to smooth over when it comes to Node.js APIs and modules.

Over time, more of these restrictions were removed. Many libraries targeting Node.js now run on Cloudflare Workers without any changes being necessary. Notably, workerd now supports:

  • node:http, node:https, node:http2 , and node:tls
  • node:dns
  • node:crypto
  • node:fs with an in-memory filesystem

These steady advancements in workerd have allowed us to become more confident in building on Cloudflare Workers, without compromising the knowledge you have for Node.js and having to swap out the packages you reach for in Node.js runtimes.

Reliability at scale

EAS Hosting now serves millions of requests every week and we’ve incorporated feedback from companies, teams, and users into it. (In May, for example, we introduced wildcard custom domains and a deployment file browser in the dashboard.)

This increase in reliability and the datapoints we gathered allowed us to also lift our restrictions on deployments and assets per deployments for Free tier users.

We’re now handling thousands of worker deployments every day and have worked on improving the speed of deployments and asset uploads since launch. The average deployment is created in less than a minute consistently, and lifting the limits has not impacted this or caused an increase in failures.

Laying a foundation for the future of Hosting

All of these changes point in one direction.

  • expo-server server-side Runtime API
  • Expo Router +middleware.ts support
  • app.json Expo Router configuration for EAS Hosting

While many of these changes and features are filling in missing functionality, they’re also a breeding ground for the future of EAS Hosting and our upcoming roadmap.

expo-server not only provides server-side APIs without increasing complexity or vendor lock-in, it also gives us a way to provide functionality and APIs that will be specific to EAS Hosting.

We’ll be working on adding value and blob file storage first, enabled by the expo-server runtime API and integrating seamlessly with EAS Hosting. However, we are also investigating database-like and namespaced KV storage functionality.

expo-server also is an API that’s designed to work in any server-side code, and enables us to confidently continue working on Server Loader Functions, React Server Functions, React Server Components, and Server-Side Rendering support in Expo Router, without being restricted by API concerns. While work on these features is still in flux, some of these features are already available as experimental previews in Expo today.

This means we’re now making progress on three aligned roadmaps:

  • Stabilizing Expo Router’s continued support for more Web and Server-side features (like React Server Functions)
  • Parallel deployments of your apps to stores, updates to users, and API code to EAS Hosting
  • Stateful features and storage APIs for EAS Hosting via expo-server

So give Hosting a try. We'd love to hear what you think.

Expo Router
EAS Hosting
API Routes

Get there faster with Expo Application Services

Learn more