Cheat sheet
Here is a quick overview of common Elysia patterns
Hello world
Section titled “Hello world”A simple hello world
import { Elysia } from 'elysia'
new Elysia() .get('/', () => 'Hello World') .listen(3000)Custom HTTP method
Section titled “Custom HTTP method”Define routes using custom HTTP methods/verbs
See Route
import { Elysia } from 'elysia'
new Elysia() .get('/hi', () => 'Hi') .post('/hi', () => 'From Post') .put('/hi', () => 'From Put') .method('M-SEARCH', '/hi', () => 'Custom Method') .listen(3000)Path parameter
Section titled “Path parameter”Using dynamic path parameters
See Path
import { Elysia } from 'elysia'
new Elysia() .get('/id/:id', ({ params: { id } }) => id) .get('/rest/*', () => 'Rest') .listen(3000)Return JSON
Section titled “Return JSON”Elysia converts responses to JSON automatically
See Handler
import { Elysia } from 'elysia'
new Elysia() .get('/json', () => { return { hello: 'Elysia' } }) .listen(3000)Return a file
Section titled “Return a file”Return file() for a single file. Use form() to return files in a multipart form-data response.
The form must be a 1-level deep object
See Handler
import { Elysia, file, form } from 'elysia'
new Elysia() .get('/cat', file('public/cat.jpg')) .get('/form', () => { return form({ hello: 'Elysia', image: file('public/cat.jpg') }) }) .listen(3000)Header and status
Section titled “Header and status”Set a custom header and a status code
See Handler
import { Elysia } from 'elysia'
new Elysia() .get('/', ({ set, status }) => { set.headers['x-powered-by'] = 'Elysia'
return status(418, "I'm a teapot") }) .listen(3000)Define a prefix once for subroutes
See Group
import { Elysia } from 'elysia'
new Elysia() .get("/", () => "Hi") .group("/auth", app => { return app .get("/", () => "Hi") .post("/sign-in", ({ body }) => body) .put("/sign-up", ({ body }) => body) }) .listen(3000)Schema
Section titled “Schema”Enforce a data type on a route
See Validation
import { Elysia, t } from 'elysia'
new Elysia() .post('/mirror', { body: t.Object({ username: t.String(), password: t.String() }) }, ({ body: { username } }) => username) .listen(3000)File upload
Section titled “File upload”See Validation#file. A type check needs a file type detector: install file-type and register it with setFileTypeDetector, otherwise every upload checked against type fails validation.
import { Elysia, t, setFileTypeDetector } from 'elysia'import { fileTypeFromBlob } from 'file-type'
setFileTypeDetector(fileTypeFromBlob)
new Elysia() .post('/body', { body: t.Object({ file: t.File({ type: 'image/*' }), multipleFiles: t.Files() }) }, ({ body }) => body) .listen(3000)Lifecycle hook
Section titled “Lifecycle hook”Intercept Elysia events in order
See Lifecycle
import { Elysia, t } from 'elysia'
new Elysia() .onRequest(() => { console.log('On request') }) .onBeforeHandle(() => { console.log('Before handle') }) .post('/mirror', { body: t.Object({ username: t.String(), password: t.String() }), afterHandle: () => { console.log("After handle") } }, ({ body }) => body) .listen(3000)Enforce a data type on subroutes
See Guard
// @errors: 2345import { Elysia, t } from 'elysia'
new Elysia() .guard({ response: t.String() }, (app) => app .get('/', () => 'Hi') // Invalid: will throws error, and TypeScript will report error .get('/invalid', () => 1) ) .listen(3000)Custom context
Section titled “Custom context”Add custom variables to route context
See Context
import { Elysia } from 'elysia'
new Elysia() .state('version', 1) .decorate('getDate', () => Date.now()) .get('/version', ({ getDate, store: { version } }) => `${version} ${getDate()}`) .listen(3000)Redirect
Section titled “Redirect”Redirect responses
See Handler
import { Elysia } from 'elysia'
new Elysia() .get('/', () => 'hi') .get('/redirect', ({ redirect }) => { return redirect('/') }) .listen(3000)Plugin
Section titled “Plugin”Create a separate instance
See Plugin
import { Elysia } from 'elysia'
const plugin = new Elysia() .state('plugin-version', 1) .get('/hi', () => 'hi')
new Elysia() .use(plugin) .get('/version', ({ store }) => store['plugin-version']) .listen(3000)WebSocket
Section titled “WebSocket”Create a realtime connection using WebSocket
See Web Socket
import { Elysia } from 'elysia'import { websocket } from 'elysia/websocket'
new Elysia() .use(websocket()) .ws('/ping', { message(ws, message) { ws.send('hello ' + message) } }) .listen(3000)OpenAPI documentation
Section titled “OpenAPI documentation”Create interactive documentation using Scalar (or optionally Swagger)
See openapi
import { Elysia } from 'elysia'import { openapi } from '@elysia/openapi'
const app = new Elysia() .use(openapi()) .listen(3000)
console.log(`View documentation at "${app.server!.url}openapi" in your browser`);Unit test
Section titled “Unit test”Write a unit test for your Elysia app
See Unit Test
import { describe, expect, it } from 'bun:test'import { Elysia } from 'elysia'
describe('Elysia', () => { it('return a response', async () => { const app = new Elysia().get('/', () => 'hi')
const response = await app .handle(new Request('http://localhost/')) .then((res) => res.text())
expect(response).toBe('hi') })})Custom body parser
Section titled “Custom body parser”Create custom logic for parsing bodies
See Parse
import { Elysia } from 'elysia'
new Elysia() .onParse(({ request, contentType }) => { if (contentType === 'application/custom-type') return request.text() })GraphQL
Section titled “GraphQL”Create a custom GraphQL server using GraphQL Yoga or Apollo
See GraphQL Yoga
import { Elysia } from 'elysia'import { yoga } from '@elysia/graphql-yoga'
const app = new Elysia() .use( yoga({ typeDefs: /* GraphQL */` type Query { hi: String } `, resolvers: { Query: { hi: () => 'Hello from Elysia' } } }) ) .listen(3000)