Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/elysiajs/documentation/llms.txt

Use this file to discover all available pages before exploring further.

Elysia maps incoming requests to handlers using the request path and HTTP method. You register routes by calling the method that matches the HTTP verb you want to handle, passing a path and a function (or a literal value) to return as the response.
import { Elysia } from 'elysia'

new Elysia()
    .get('/', 'hello')
    .get('/hi', 'hi')
    .listen(3000)

Path types

Elysia recognises three kinds of paths, and you can mix all three in the same instance.

Static paths

Hardcoded strings that match exactly one URL.

Dynamic paths

Named segments (:id) that capture a value from the URL.

Wildcards

An * segment that captures everything after a given prefix.
import { Elysia } from 'elysia'

new Elysia()
    .get('/id/1', 'static path')
    .get('/id/:id', 'dynamic path')
    .get('/id/*', 'wildcard path')
    .listen(3000)

Static path

A static path is a fixed string. Elysia resolves static paths before dynamic paths, so /id/1 takes priority over /id/:id.
import { Elysia } from 'elysia'

new Elysia()
    .get('/hello', 'hello')
    .get('/hi', 'hi')
    .listen(3000)

Dynamic path

A dynamic path uses a colon prefix (:name) to capture a URL segment into context.params.
import { Elysia } from 'elysia'

new Elysia()
    .get('/id/:id', ({ params: { id } }) => id)
    .listen(3000)
PathResponse
/id/11
/id/anythinganything
/idNot Found
/id/a/bNot Found
You can include as many parameters as you need — each one becomes a key on params.
import { Elysia } from 'elysia'

new Elysia()
    .get('/id/:id/:name', ({ params: { id, name } }) => id + ' ' + name)
    .listen(3000)

Optional path parameters

Append ? to a parameter name to make it optional so that both /id and /id/1 match the same handler.
import { Elysia } from 'elysia'

new Elysia()
    .get('/id/:id?', ({ params: { id } }) => `id ${id}`)
    .listen(3000)

Wildcards

Use * to capture the rest of the URL, including slashes, into params['*'].
import { Elysia } from 'elysia'

new Elysia()
    .get('/id/*', ({ params }) => params['*'])
    .listen(3000)

Path priority

When multiple path patterns could match the same request, Elysia resolves them in this order:
  1. Static paths
  2. Dynamic paths
  3. Wildcards
import { Elysia } from 'elysia'

new Elysia()
    .get('/id/1', 'static path')   // wins for /id/1
    .get('/id/:id', 'dynamic path') // wins for /id/2
    .get('/id/*', 'wildcard path')  // wins for /id/2/a
    .listen(3000)

HTTP methods

Elysia exposes a dedicated method for each common HTTP verb.
import { Elysia } from 'elysia'

new Elysia()
    .get('/users', () => [])
    .listen(3000)
Retrieve data without side effects.

Match any method

.all() responds to every HTTP method for a path.
import { Elysia } from 'elysia'

new Elysia()
    .all('/', 'hi')
    .listen(3000)

Custom HTTP methods

Use .route() to handle non-standard verbs. Per RFC 7231, HTTP verbs are case-sensitive — use uppercase by convention.
import { Elysia } from 'elysia'

new Elysia()
    .get('/get', 'hello')
    .post('/post', 'hi')
    .route('M-SEARCH', '/m-search', 'connect')
    .listen(3000)
.route() accepts: method, path, handler, and an optional hook object.

Route grouping

When several routes share the same prefix, .group() keeps your code flat and removes duplication.
import { Elysia } from 'elysia'

// Without grouping
new Elysia()
    .post('/user/sign-in', 'Sign in')
    .post('/user/sign-up', 'Sign up')
    .post('/user/profile', 'Profile')

// With grouping
new Elysia()
    .group('/user', (app) =>
        app
            .post('/sign-in', 'Sign in')
            .post('/sign-up', 'Sign up')
            .post('/profile', 'Profile')
    )
    .listen(3000)
Both produce identical routes:
PathResponse
/user/sign-inSign in
/user/sign-upSign up
/user/profileProfile
.group() also accepts an optional guard object as its second argument to apply validation or hooks to every route in the group.
import { Elysia, t } from 'elysia'

new Elysia()
    .group(
        '/user',
        { body: t.Literal('Rikuhachima Aru') },
        (app) => app
            .post('/sign-in', 'Sign in')
            .post('/sign-up', 'Sign up')
    )
    .listen(3000)

Prefix (plugin-based grouping)

For larger codebases you can move a group of routes into a separate Elysia instance using the prefix constructor option, then compose it with .use().
import { Elysia } from 'elysia'

const users = new Elysia({ prefix: '/user' })
    .post('/sign-in', 'Sign in')
    .post('/sign-up', 'Sign up')
    .post('/profile', 'Profile')

new Elysia()
    .use(users)
    .get('/', 'hello world')
    .listen(3000)
Prefix-based plugins are the idiomatic way to split a large Elysia app into modules. Each plugin is a fully independent Elysia instance that can be tested in isolation.

Programmatic testing

Elysia.handle() processes a real Request object, making it useful for unit tests without spinning up an HTTP server.
import { Elysia } from 'elysia'

const app = new Elysia()
    .get('/', 'hello')
    .post('/hi', 'hi')
    .listen(3000)

app.handle(new Request('http://localhost/')).then(console.log)

Build docs developers (and LLMs) love