Skip to main content
Routing in Elysia is the process of mapping HTTP methods and URL patterns to handler functions. Elysia provides a simple, chainable API for defining routes.

Basic routing

Define routes using HTTP method functions like .get(), .post(), .put(), .delete(), and more:
import { Elysia } from 'elysia'

const app = new Elysia()
  .get('/', () => 'Hello World')
  .post('/user', () => 'Create user')
  .put('/user/:id', () => 'Update user')
  .delete('/user/:id', () => 'Delete user')
  .listen(3000)

Route patterns

Static routes

Static routes match exact paths:
app
  .get('/', () => 'Root')
  .get('/about', () => 'About')
  .get('/contact/info', () => 'Contact Info')

Path parameters

Capture dynamic segments using the :param syntax:
app.get('/id/:id', ({ params: { id } }) => id)

app.get('/user/:id/:name', ({ params: { id, name } }) => {
  return `User ${name} with ID ${id}`
})
Path parameters are automatically extracted and available in the params object of the context.

Optional parameters

Make parameters optional using the ? suffix:
app.get('/id/:id?', ({ params: { id } }) => {
  return id || 'No ID provided'
})

app.get('/user/:id?/:name?', ({ params }) => {
  const { id = 'unknown', name = 'anonymous' } = params
  return `User ${name} with ID ${id}`
})

Wildcard routes

Match any path segment using the * wildcard:
app.get('/public/*', () => 'Public files')

app.get('/api/*/status', () => 'Status endpoint')

HTTP methods

Elysia supports all standard HTTP methods:
app.get('/users', () => getAllUsers())
Used for retrieving resources.

Path prefixes

Set a prefix for all routes using the prefix configuration:
const app = new Elysia({ 
  prefix: '/api/v1' 
})
  .get('/users', () => 'Users') // /api/v1/users
  .get('/posts', () => 'Posts') // /api/v1/posts

Route grouping

Group related routes with a common prefix:
app.group('/api', (app) => 
  app
    .get('/users', () => 'Get users')
    .post('/users', () => 'Create user')
)

app.group('/admin', (app) => 
  app
    .get('/dashboard', () => 'Dashboard')
    .get('/settings', () => 'Settings')
)

Query strings

Access query parameters through the query object:
app.get('/', ({ query: { id } }) => {
  return `ID: ${id}`
})
// GET /?id=123 → "ID: 123"

app.get('/search', ({ query }) => {
  const { q, limit = '10', offset = '0' } = query
  return { query: q, limit, offset }
})
// GET /search?q=elysia&limit=20 → {"query":"elysia","limit":"20","offset":"0"}

Strict path mode

By default, Elysia ignores trailing slashes. Enable strict path matching:
const app = new Elysia({ 
  strictPath: true 
})
  .get('/users', () => 'Users') // Only matches /users
  .get('/posts/', () => 'Posts') // Only matches /posts/
With strictPath: true, /users and /users/ are treated as different routes.

Router history

Access all registered routes:
const app = new Elysia()
  .get('/', () => 'Home')
  .post('/users', () => 'Create')

console.log(app.routes)
// [
//   { method: 'GET', path: '/', ... },
//   { method: 'POST', path: '/users', ... }
// ]

Best practices

Follow REST conventions:
  • GET for reading
  • POST for creating
  • PUT for full updates
  • PATCH for partial updates
  • DELETE for removing
Prefer /users/:id/posts over deeply nested routes like /api/v1/users/:userId/posts/:postId/comments/:commentId.
Group related routes together to improve code organization and maintainability.

Next steps

Handlers

Learn how to write request handlers

Context

Understand the context object

Build docs developers (and LLMs) love