Elysia 0.2 - The Blessing | ElysiaJS

ID: 2230https://elysiajs.com/blog/elysia-02
Source

Elysia 0.2 – The Blessing

“Blessing” brings many improvements, mainly in TypeScript performance, type‑inference, better auto‑completion, and new features to reduce boilerplate.

Author: saltyaom – 29 Jan 2023

Blue to purple aurora in the night sky above snow mountain


Defers / Lazy Loading Module

Elysia 0.2 introduces support for lazy‑loading modules and asynchronous plugins.
This allows you to defer plugin registration and apply plugins incrementally after the server has started, achieving the fastest possible start‑up time in Serverless/Edge environments.

const plugin = async (app: Elysia) => {
  const stuff = await doSomeHeavyWork()

  return app.get('/heavy', stuff)
}

app.use(plugin)

Lazy Loading

Heavy modules can be skipped at startup and loaded only when needed:

app.use(import('./some-heavy-module'))

This registers the module after it has finished importing, making the module lazy‑load.
Deferred plugins and lazy‑loading modules enjoy full type‑inference right out of the box.


Reference Model

Elysia can now memorize schemas and reference them directly in schema fields without the need for an import file via Elysia.setModel.
This list of available schemas provides auto‑completion, complete type‑inference, and validation as if you were using inline schemas.

const app = new Elysia()
  .setModel({
    sign: t.Object({
      username: t.String(),
      password: t.String(),
    })
  })
  .post('/sign', ({ body }) => body, {
    schema: {
      body: 'sign',
      response: 'sign',
    }
  })

This gives you auto‑completion of known models:

Screenshot 2566-01-23 at 13 24 28

It also prevents returning an invalid type:

Screenshot 2566-01-23 at 13 26 00

When using @elysiajs/swagger, a separate Model section will list the available models:

Screenshot 2566-01-23 at 13 23 41

References also perform validation as expected.
In short, it’s the same as using inline schemas but with a simpler name‑based reference.


OpenAPI Detail Field

A new field schema.detail lets you customize route details following the OpenAPI Schema V2 standard, with full auto‑completion.

OpenAPI Detail screenshot

This improves documentation and gives you a fully editable Swagger UI:

Swagger UI screenshot


Union Type

The previous version sometimes mishandled distinct union types, as Elysia tried to capture the response for a full type reference for Eden, leading to invalid types.


Union Response

With the union type support, you can return multiple response statuses via schema.response[statusCode].

app
  .post('/json/:id', ({ body, params: { id } }) => ({
    ...body,
    id,
  }), {
    schema: {
      body: 'sign',
      response: {
        200: t.Object({
          username: t.String(),
          password: t.String(),
          id: t.String(),
        }),
        400: t.Object({
          error: t.String(),
        }),
      },
    },
  })

Elysia validates all schemas in response, allowing one of the types to be returned.
Return types are also reported in Swagger’s response section.


Faster Type Inference

Elysia 0.1 explored using type inference to improve the developer experience, but sometimes it caused long update times due to heavy type unwrapping.
Elysia 0.2 optimizes type inference for speed, avoiding duplication of heavy type unwrapping and improving performance when updating types.


Ecosystem

Enabling async plugins and deferred modules unlocks many new plugins that were previously impossible.
Examples include:

  • Elysia Static plugin with non‑blocking capability
  • Eden with union‑type inference for multiple responses
  • New Elysia Apollo plugin

Notable Improvements

  • onRequest and onParse can now access PreContext
  • Support for application/x-www-form-urlencoded by default
  • Body parser now handles content‑type with extra attributes (e.g., application/json;charset=utf-8)
  • URI path parameters are decoded
  • Eden reports an error if Elysia is not installed
  • Skip declaration of existing models and decorators

Breaking Changes

  • onParse now accepts (context: PreContext, contentType: string) instead of (request: Request, contentType: string).
    To migrate, add .request to the context to access the Request.

Afterward

Thank you for supporting Elysia and for your interest in this project.
This release brings better DX and hopefully everything you need to write great software with Bun.

We now have a Discord server where you can ask questions or just hang out—everyone is welcome.
With these wonderful tools, we are excited to see what amazing software you will build.

Not to be part of those images someone paints
Not advancing in that show chosen by someone else
You and I, alive to write our story
Will never let you be lone and be gone from your side