Skip to content
Our Sponsors
Open in Anthropic

Integration with Expo

Starting from Expo SDK 50, and App Router v3, Expo allows us to create API route directly in an Expo app.

  1. Create app/[...slugs]+api.ts
  2. Define an Elysia server
  3. Export Elysia.fetch with the name of the HTTP methods you want to use
typescript
import { Elysia, t } from 'elysia'

const app = new Elysia()
    .get('/', 'hello Expo')
    .post('/', ({ body }) => body, {
        body: t.Object({
            name: t.String()
        })
    })

export const GET = app.fetch 
export const POST = app.fetch 

You can treat the Elysia server as if it were a normal Expo API route.

pnpm

If you use pnpm, pnpm doesn't auto install peer dependencies by default forcing you to install additional dependencies manually.

bash
pnpm add @sinclair/typebox openapi-types

Prefix

If you place an Elysia server not in the root directory of the app router, you need to annotate the prefix on the Elysia server.

For example, if you place the Elysia server in app/api/[...slugs]+api.ts, you need to annotate the prefix as /api on the Elysia server.

typescript
import { Elysia, t } from 'elysia'

const app = new Elysia({ prefix: '/api' }) 
    .get('/', 'Hello Expo')
    .post('/', ({ body }) => body, {
        body: t.Object({
            name: t.String()
        })
    })

export const GET = app.fetch
export const POST = app.fetch

This will ensure that Elysia routing works properly wherever you place it.

Eden

We can add Eden for end-to-end type safety similar to tRPC.

  1. Export type from the Elysia server
typescript
import { Elysia } from 'elysia'

const app = new Elysia()
	.get('/', 'Hello Nextjs')
	.post(
		'/user',
		({ body }) => body,
		{
			body: treaty.schema('User', {
				name: 'string'
			})
		}
	)

export type app = typeof app 

export const GET = app.fetch
export const POST = app.fetch
  1. Create a Treaty client
typescript
import { treaty } from '@elysiajs/eden'
import type { app } from '../app/[...slugs]+api'

export const api = treaty<app>('localhost:3000/api')
  1. Use the client in both server and client components
tsx
import { api } from '../lib/eden'

export default async function Page() {
	const message = await api.get()

	return <h1>Hello, {message}</h1>
}

Deployment

You can either directly use the API route with Elysia and deploy as a normal Elysia app if needed, or use the experimental Expo server runtime.

If you are using the Expo server runtime, you may use the expo export command to create an optimized build for your Expo app. This will include an Expo function that uses Elysia at dist/server/_expo/functions/[...slugs]+api.js

TIP

Please note that Expo Functions are treated as Edge functions instead of normal servers, so running the Edge function directly will not allocate any port.

You may use the Expo function adapter provided by Expo to deploy your Edge Function.

Currently, Expo supports the following adapters: