Skip to content

TypeBox

Import t from elysia to write schemas that validate values at runtime and infer their TypeScript types.

This reference covers primitive types, Elysia types, and Elysia’s conversion behavior.

TypeBox schemas use familiar TypeScript names, such as String, Number, Boolean, and Object. It also provides Intersect, KeyOf, and Tuple for more complex types.

To validate a request body as a string, pass t.String() in the route’s schema before the handler.

import { Elysia, t } from 'elysia'
new Elysia()
.post('/', {
body: t.String()
}, ({ body }) => `Hello ${body}`)
.listen(3000)

Elysia runs the handler when the body matches. Otherwise, it raises a validation error through the error lifecycle.

TypeBoxTypeScript
t.String()string
t.Number()number
t.Boolean()boolean
t.Array(t.Number())number[]
t.Object({ x: t.Number() }){ x: number }
t.Null()null
t.Literal(42)42

Elysia re-exports TypeBox types alongside its HTTP-specific types. See the TypeBox reference for the full API.

Pass options to add validation constraints. These follow JSON Schema keywords.

import { t } from 'elysia'
// Accepts '[email protected]'
t.String({ format: 'email' })
// Accepts numbers from 10 through 100
t.Number({ minimum: 10, maximum: 100 })
// Accepts one through five numbers
t.Array(t.Number(), {
minItems: 1,
maxItems: 5
})
// Accepts { x: 100, y: 200 }
t.Object({ x: t.Number() }, {
additionalProperties: true
})

See the JSON Schema validation specification for the individual keywords.

These patterns help you combine schemas and make fields optional.

Use t.Union to accept any of the listed types. It can be used on its own or as a field in t.Object.

import { t } from 'elysia'
// TypeScript: string | number
// Accepts 'Hello' or 123
t.Union([
t.String(),
t.Number()
])

Wrap a field in t.Optional to allow it to be omitted.

import { t } from 'elysia'
// TypeScript: { x: number, y?: number }
// Accepts { x: 123 }
t.Object({
x: t.Number(),
y: t.Optional(t.Number())
})

Use t.Partial to make every field in an object optional.

import { t } from 'elysia'
// TypeScript: { x?: number, y?: number }
// Accepts { y: 123 }
t.Partial(
t.Object({
x: t.Number(),
y: t.Number()
})
)

Elysia adds types for HTTP data, including files, cookies, and values encoded as strings.

TypeAccepts
UnionEnumOne of a list of literal values
FileA single file
FilesFiles in a single field
CookieA cookie jar with validation and cookie options
NullableA matching value or null
MaybeEmptyA matching value, null, or undefined
FormA FormData response
Uint8ArrayA Uint8Array or an ArrayBuffer to convert
ArrayBufferAn ArrayBuffer
ObjectStringAn object or a JSON object string
BooleanStringA boolean or its string representation
NumericA number or numeric string

Accept one of the listed values. Values can be strings, numbers, or null.

import { t } from 'elysia'
t.UnionEnum(['rapi', 'anis', 1, null])

Validate a single uploaded file.

import { t } from 'elysia'
t.File()

Restrict the file’s media type, such as image/png or image. An array accepts any of its listed types.

import { t } from 'elysia'
t.File({ type: ['image/png', 'image/jpeg'] })

Set the lower file-size bound in bytes or use a k or m suffix. The file size must be at least the bound.

import { t } from 'elysia'
t.File({ minSize: '1k' })

Set the upper file-size bound in bytes or use a k or m suffix. The file size must not exceed the bound.

import { t } from 'elysia'
t.File({ maxSize: '5m' })
SuffixBytes
k1,024
m1,048,576

Both size options accept a number or a string such as '512k'.

Use t.Files for files in one field. It supports the File options and array length constraints such as minItems and maxItems.

import { t } from 'elysia'
t.Files()

Describe a cookie jar with object properties and cookie configuration.

import { t } from 'elysia'
t.Cookie({
name: t.String()
})

See cookies for reading, writing, and signing cookie values.

Pass secrets in the second argument to sign cookies. A string uses one key; an array supports key rotation.

import { t } from 'elysia'
t.Cookie({ name: t.String() }, {
secrets: ['current-secret', 'previous-secret'],
sign: ['name']
})

New cookies use the first secret, which must be a non-empty string. Replace the example secrets with private application secrets.

Accept a matching value or null, but not undefined.

import { t } from 'elysia'
t.Nullable(t.String())

Accept a matching value, null, or undefined. An empty string is accepted only if the wrapped schema accepts it.

import { t } from 'elysia'
t.MaybeEmpty(t.String())

Use t.Form to validate a FormData response returned by the form helper.

import { t } from 'elysia'
t.Form({
someValue: t.File()
})

Accept an ArrayBuffer or Uint8Array and decode it to a Uint8Array. Pair it with the arrayBuffer body parser for binary uploads.

import { Elysia, t } from 'elysia'
new Elysia()
.post('/upload', {
parse: 'arrayBuffer',
body: t.Uint8Array()
}, ({ body }) => body.byteLength)

The API spelling is t.Uint8Array(), not t.UInt8Array().

Validate an ArrayBuffer without converting it to a typed array.

import { Elysia, t } from 'elysia'
new Elysia()
.post('/upload', {
parse: 'arrayBuffer',
body: t.ArrayBuffer()
}, ({ body }) => body.byteLength)

Accept an object or a JSON string that decodes to the specified object. This is useful in query strings, headers, and FormData fields.

import { t } from 'elysia'
// Accepts { name: 'Rapi' } or '{"name":"Rapi"}'
t.ObjectString({
name: t.String()
})

Accept a boolean or the strings 'true' and 'false', then decode the result to a boolean.

import { t } from 'elysia'
t.BooleanString()

Accept a number or numeric string, then decode the result to a number. This is useful for path parameters and query values.

import { t } from 'elysia'
t.Numeric({ minimum: 1, maximum: 100 })

Numeric supports the same numeric constraints as t.Number.

Elysia converts common string-based HTTP inputs before your handler runs. Creating a schema outside a route doesn’t apply these route conversions.

You can wrap the entire request schema in t.Optional, as well as individual object fields. This also applies to body and header schemas.

import { Elysia, t } from 'elysia'
new Elysia()
.get('/optional', {
query: t.Optional(
t.Object({
name: t.String()
})
)
}, ({ query }) => query)

/optional can omit the query entirely. When a non-empty query is provided, it must contain a string name.

Elysia converts t.Number at the root and direct properties of string-based request schemas, such as params, query, and headers, to numeric conversion. It also converts a root numeric body, but a number inside a JSON body object stays a number.

import { Elysia, t } from 'elysia'
new Elysia()
.post('/:id', {
params: t.Object({
// The path string becomes a number
id: t.Number()
}),
body: t.Object({
// JSON must contain a number, not a string
id: t.Number()
})
}, ({ params, body }) => ({
pathId: params.id,
bodyId: body.id
}))
// No route conversion here
t.Number()

For /42 with {"id": 10}, both handler values are numbers. A JSON body of {"id": "10"} fails validation.

Boolean conversion follows the same rule as numeric conversion. Direct path, query, and header fields accept string booleans; a boolean inside a JSON object stays a boolean.

import { Elysia, t } from 'elysia'
new Elysia()
.post('/:enabled', {
params: t.Object({
// The path string becomes a boolean
enabled: t.Boolean()
}),
body: t.Object({
// JSON must contain a boolean, not a string
enabled: t.Boolean()
})
}, ({ params, body }) => ({
pathEnabled: params.enabled,
bodyEnabled: body.enabled
}))
// No route conversion here
t.Boolean()

For /true with {"enabled": false}, the handler receives true and false. A JSON body of {"enabled": "false"} fails validation.

Type to search the documentation.

    Up arrowDown arrow to navigateEnter to selectEscape to close