Integration with Tanstack Start
Elysia can run inside Tanstack Start server routes.
- Create src/routes/api.$.ts
- Define an Elysia server
- Export Elysia handler in server.handlers
import { Elysia } from 'elysia'
import { createFileRoute } from '@tanstack/react-router'
import { createIsomorphicFn } from '@tanstack/react-start'
const app = new Elysia({
prefix: '/api'
}).get('/', 'Hello Elysia!')
const handle = ({ request }: { request: Request }) => app.fetch(request)
export const Route = createFileRoute('/api/$')({
server: {
handlers: {
GET: handle,
POST: handle
}
}
})Elysia should now be running on /api.
We may add additional methods to server.handlers to support other HTTP methods as needed.
pnpm
If you use pnpm, pnpm doesn't auto install peer dependencies by default forcing you to install additional dependencies manually.
pnpm add @sinclair/typebox openapi-typesEden
We can add Eden for end-to-end type safety similar to tRPC.
import { Elysia } from 'elysia'
import { treaty } from '@elysiajs/eden'
import { createFileRoute } from '@tanstack/react-router'
import { createIsomorphicFn } from '@tanstack/react-start'
const app = new Elysia({
prefix: '/api'
}).get('/', 'Hello Elysia!')
const handle = ({ request }: { request: Request }) => app.fetch(request)
export const Route = createFileRoute('/api/$')({
server: {
handlers: {
GET: handle,
POST: handle
}
}
})
export const getTreaty = createIsomorphicFn()
.server(() => treaty(app).api)
.client(() => treaty<typeof app>('localhost:3000').api) Notice that we use createIsomorphicFn to create a separate Eden Treaty instance for both server and client.
- On server, Elysia is called directly without HTTP overhead.
- On client, we call the Elysia server through HTTP.
In a React component, we can use getTreaty to call the Elysia server with type safety.
Loader Data
Tanstack Start supports Loader to fetch data before rendering the component.
import { createFileRoute } from '@tanstack/react-router'
import { getTreaty } from './api.$'
export const Route = createFileRoute('/a')({
component: App,
loader: () => getTreaty().get().then((res) => res.data)
})
function App() {
const data = Route.useLoaderData()
return data
}Calling Elysia in a loader executes it on the server during SSR and doesn’t incur HTTP overhead. When navigating from one page to another, the loader will run on the client-side, making an HTTP request to the endpoint.
Eden Treaty will ensure type safety on both server and client.
React Query
We can also use React Query to interact with Elysia server on client.
import { createFileRoute } from '@tanstack/react-router'
import { useQuery } from '@tanstack/react-query'
import { getTreaty } from './api.$'
export const Route = createFileRoute('/a')({
component: App
})
function App() {
const { data: response } = useQuery({
queryKey: ['get'],
queryFn: () => getTreaty().get()
})
return response?.data
}This can work with any React Query features like caching, pagination, infinite queries, etc.
Please visit Tanstack Start Documentation for more information about Tanstack Start.