ElysiaはTypeScriptでWeb APIを構築するためのフレームワークです。Bun向けに設計され、route、schema validation、lifecycle hook、plugin、OpenAPI連携、型付きclientのEdenなどを提供します。
この記事の結論
記事情報: 2024年12月29日初出。Elysia公式ドキュメントを2026年7月25日に再確認しています。
Elysiaの特徴は、server側のroute schemaからrequest・responseの型を推論し、必要ならEdenを通じてclientへ共有できる点です。一方、「最速」という単一のベンチマークだけで選ぶべきではありません。Bunでの運用経験、pluginの成熟度、OpenAPIを境界にするか、clientとserverを同じTypeScript型で結ぶかを含めて判断します。
最小のAPI
ElysiaではHTTP methodとpathをchainしてrouteを定義します。
import { Elysia } from "elysia";
const app = new Elysia()
.get("/", () => ({ message: "Hello" }))
.get("/users/:id", ({ params }) => ({
id: params.id,
}))
.listen(3000);
console.log(`Listening on ${app.server?.port}`);
導入はBunを前提にした公式手順を確認します。
bun create elysia app
cd app
bun run dev
Elysia自体はWeb Standard APIを重視し、adapterを通じた別runtimeの選択肢も案内されています。ただしpluginや機能が同じ範囲で動くとは限りません。Bun以外を対象にする場合は、対象adapterの公式ページと制限を確認します。
schema validationと型推論
Elysiaのtを使うと、body、query、params、headers、responseにschemaを定義できます。実行時には入力を検証し、TypeScript側ではhandlerの型として推論されます。
import { Elysia, t } from "elysia";
const app = new Elysia().post(
"/users",
({ body }) => ({
id: crypto.randomUUID(),
name: body.name,
}),
{
body: t.Object({
name: t.String({ minLength: 1, maxLength: 80 }),
}),
response: t.Object({
id: t.String(),
name: t.String(),
}),
},
);
TypeScriptの型注釈だけは実行時に消えます。外部から届くJSONを守るには、route schemaによる実行時検証が必要です。文字列長やformatだけでなく、業務上の権限や一意性はservice層・DB側でも検証します。
response schemaを定義すると、APIの契約が明確になります。ただし内部エラーの詳細をそのまま返さないよう、正常応答とエラー応答を設計し、ログへ残す情報とclientへ返す情報を分けてください。
lifecycle hook
Elysiaはrequestの受信からresponseまでに複数のlifecycleを持ち、onRequest、beforeHandle、afterHandle、onErrorなどで共通処理を登録できます。
const app = new Elysia()
.onRequest(({ request }) => {
console.log(request.method, new URL(request.url).pathname);
})
.onError(({ code, error, set }) => {
set.status = code === "VALIDATION" ? 400 : 500;
return {
error: code === "VALIDATION" ? "invalid_request" : "internal_error",
};
});
hookは便利ですが、順序と適用範囲を理解せず増やすと処理を追いにくくなります。認証、logging、error mappingなど責務ごとにpluginへ分け、route固有の処理はhandlerの近くへ置きます。
また、秘密情報やrequest body全体をログへ出さないようにします。認証header、cookie、password、token、個人情報は明示的に除外してください。
pluginとscope
再利用するrouteやhookはElysia instanceとしてまとめ、useで組み込めます。
const healthPlugin = new Elysia({ name: "health" })
.get("/health", () => ({ status: "ok" }));
const app = new Elysia()
.use(healthPlugin)
.listen(3000);
Elysiaのlifecycle hookにはlocal、scoped、globalなどの適用範囲があります。pluginを作るときは「登録先のrouteだけに効くのか、親や後続routeにも効くのか」を公式のscope資料で確認します。
第三者pluginを採用する場合は、対応するElysia・Bunのversion、保守状況、認証やerror handlingへの影響を調べます。pluginが少ないこと自体を避ける理由にする必要はありませんが、重要機能を自分たちで保守できるかは運用判断になります。
Edenによるend-to-end型安全性
Eden Treatyは、Elysia serverの型をTypeScript clientへ渡し、routeをobjectのように呼び出す仕組みです。code generationを使わず、TypeScriptの型推論でrequestとresponseを結びます。
// server.ts
export const app = new Elysia()
.get("/users/:id", ({ params }) => ({ id: params.id }));
export type App = typeof app;
// client.ts
import { treaty } from "@elysiajs/eden";
import type { App } from "./server";
const api = treaty<App>("http://localhost:3000");
const { data, error } = await api.users({ id: "42" }).get();
serverとclientを同じmonorepoで管理する場合は、変更が型へすぐ反映される利点があります。一方、別言語のclient、外部公開API、独立releaseでは、TypeScript型だけを契約にすると利用者が限定されます。その場合はOpenAPIを公開契約にし、Edenは内部clientに限定する設計も考えられます。
型安全性は認証や認可を保証しません。正しい型のidが届いても、その利用者が対象resourceを読めるとは限らないため、server側で権限を検証します。
OpenAPI・WebSocket・stream
Elysiaは公式pluginを通じてOpenAPI documentを生成できます。schemaをrouteの近くに置くと、validation、型、API documentのずれを減らせます。ただしdescription、認証方式、error response、exampleなどは自動推論だけでは不十分な場合があり、公開前に生成結果を確認します。
WebSocketやstreaming responseも扱えます。採用時には通常requestだけでなく、接続切断、backpressure、timeout、proxyの設定、graceful shutdownを試します。localで接続できることと、本番のload balancerを通して安定することは同じではありません。
アプリの構成
小規模APIでも、すべてを1つのchainへ書き続けるとテストが難しくなります。次のように責務を分けると保守しやすくなります。
- route: HTTPの入力・出力schemaとstatus
- service: 業務ルール
- repository: DBや外部API
- plugin: 認証、logging、共通error処理
- client contract: EdenまたはOpenAPI
handlerでは入力を受け、serviceを呼び、HTTP responseへ変換する範囲に留めます。DB queryや複雑な業務ルールをroute chainへ直接埋め込まないようにします。
選定チェックリスト
Elysiaを検討するときは、サンプルの短さや公開ベンチマークだけでなく、次を実際の要件で確認します。
- 対象runtimeとdeployment先が公式に対応しているか
- DB driver、認証、監視SDKが動くか
- schemaから期待するOpenAPIが生成されるか
- Edenの型共有がrepository構成に合うか
- error、shutdown、WebSocket再接続をテストできるか
- version更新時のbreaking changeを追えるか
Elysiaは、BunとTypeScriptを中心に、実行時validationと型推論を近づけたいAPIに向いています。既存Node.js資産をそのまま使うことや、公開APIの長期互換性を優先する場合は、依存パッケージと契約管理を先に検証してください。