Elysia 0.4 - 月夜の音楽会 (Moonlit Night Concert) | ElysiaJS

ID: 2210https://elysiajs.com/blog/elysia-04
Source

Elysia 0.4 – 月夜の音楽会 (Moonlit Night Concert)
Published 30 Mar 2023 by @saltyaom

Moonlit Night Concert


Overview

Named after the opening music of “The Liar Princess and the Blind Prince” trailer, 「月夜の音楽会」 (Moonlit Night Concert) is a composition by Akiko Shikata.
This release does not introduce a flashy new feature, but it lays a stronger foundation and brings several internal improvements that will benefit future versions of Elysia.


Ahead of Time Compile

Elysia used to perform dynamic checks at runtime for lifecycle hooks, validation schemas, and async determination.
This adds unnecessary overhead, especially when a route is sync but ends up being compiled as async due to the presence of a conditional async check.

What’s changed?

  • Ahead‑of‑Time Compilation now analyses route definitions at compile time.
  • Unused lifecycle hooks and validation are stripped out.
  • Routes that can remain sync stay sync, eliminating the extra tick.

TypeBox 0.26

Elysia re‑exports the TypeBox validation library as Elysia.t.
The update from 0.25.4 to 0.26.8 introduces:

  • Not type
  • Convert for coercion
  • Error.First() (retrieves the first error instead of iterating)

These changes reduce overhead and bring new features for future use.
See the TypeBox release notes.


Validate Response Per Status

Before 0.4, response validation for multiple status codes used a union type:

app.post('/strict-status', process, {
  schema: {
    response: {
      200: t.String(),
      400: t.Number(),
    }
  }
})

This could allow a non‑string 200 response to pass validation because the union logic was used.
Now each status code is validated independently, ensuring stricter contract enforcement.


Separation of Elysia Fn

Elysia Fn is a powerful feature that allows server‑side functions to be used client‑side with full type safety, even for primitives like Error, Set, and Map.
To keep the core lightweight, @elysiajs/fn is now an explicit dependency.

  • Servers not using Fn stay lighter.
  • Attempting to use Fn without installing @elysiajs/fn will trigger a type warning and runtime error.

No migration is required other than the explicit install.


Conditional Route

A new .if() method lets you register routes or plugins conditionally:

const isProduction = process.env.NODE_ENV === 'production'

const app = new Elysia()
  .if(!isProduction, (app) => app.use(swagger()))

Eden Treaty will treat these as normal routes/plugins.


Custom Validation Error

Thanks to #31, you can now customize the error response:

new Elysia()
  .onError(({ code, error, set }) => {
    if (code === 'NOT_FOUND') {
      set.status = 404
      return 'Not Found :('
    }

    if (code === 'VALIDATION') {
      set.status = 400
      return {
        fields: error.all()
      }
    }
  })
  .post('/sign-in', () => 'hi', {
    schema: {
      body: t.Object({
        username: t.String(),
        password: t.String()
      })
    }
  })
  .listen(3000)

You can now expose a detailed validation error payload instead of just the first error.


Notable Improvements

  • Updated TypeBox to 0.26.8
  • Inline response type declarations
  • Refactored types for faster responses
  • Adopted Error().First() from TypeBox
  • Added innerHandle for returning actual responses (benchmarking)

Breaking Change

  • The .fn feature is now separated into @elysiajs/fn.

Afterward

While this release may not introduce a headline‑grabbing feature, it strengthens the foundation and proves the viability of future enhancements.
Excited to see where we go from here!


the moonlit night concert, our secret
let’s start again without letting go of this hand

the moonlit night concert, our bonds
I want to tell you, “you are not a liar”

the memories in my heart is like flower that keeps blooming
no matter what you look like, you are my songstress
be by my side tonight