elysia/SKILL.md
Elysia — Bun-native web framework with end-to-end type safety and Eden Treaty typed client. Use when building with Elysia or asking about its routing, plugins, lifecycle hooks, validation, Eden Treaty, WebSocket, SSE, or integration with Bun. Fetch live documentation for up-to-date details.
npx skillsauth add mikkelkrogsholm/dev-skills elysiaInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
CRITICAL: Your training data for Elysia is unreliable. APIs change between versions and memorized patterns may be wrong or deprecated. Before writing any code, you MUST use
WebFetchto read the live docs:
WebFetch("https://elysiajs.com/llms.txt")Do not proceed without fetching this URL first. Never assume an API exists — verify against current docs.
Elysia is a Bun-native web framework designed for end-to-end type safety. Types flow from server route definitions to the client via Eden Treaty — no codegen, no manual type syncing.
Elysia has built-in features that typically require separate libraries in Express/Fastify/Hono:
t.Object(), t.String(), etc. (TypeBox) for request/response validation — no Zod middleware neededws or socket.ioeventsource polyfill@elysiajs/swagger — no manual spec writing@elysiajs/static serves files with caching headers — no serve-static@elysiajs/cors with typed config — no cors package@elysiajs/bearer extracts and validates tokens — no custom middlewaret.File() and t.Files() validators for multipart handlingUse .group() for route organization, not separate Elysia instances. Groups share the parent's type context and lifecycle hooks. Creating separate new Elysia() instances and merging with .use() works, but loses the type-level connection that makes Eden Treaty useful across route boundaries.
Eden Treaty requires exporting the app type, not the app. The client needs typeof app, not the runtime instance. A common mistake:
// server
const app = new Elysia()
.get('/users', () => getUsers())
.listen(3000)
export type App = typeof app // ← this is what Eden needs
// client
import type { App } from '../api'
import { treaty } from '@elysiajs/eden'
const api = treaty<App>('localhost:3000')
const { data } = await api.users.get() // fully typed
Lifecycle hooks run in a specific order. The chain is: onRequest → onParse → onTransform → onBeforeHandle → handler → onAfterHandle → onMapResponse → onAfterResponse. Auth guards belong in onBeforeHandle, not onRequest — putting them in onRequest runs before body parsing, so you can't read the request body for auth decisions.
derive and resolve add typed context. Use derive to add request-scoped values (runs on every request) and resolve for values that depend on validation (runs after schema validation). Both inject into the handler's typed context automatically — no manual type annotations needed.
Schema validation doubles as documentation. Every t.Object() schema on a route is automatically reflected in the Swagger UI. Adding t.String({ description: 'User ID' }) improves both validation errors and API docs simultaneously.
Error handling uses error() helper, not thrown exceptions. Return error(404, 'Not found') instead of throw new Error(). The error() helper preserves type safety in the response type — thrown exceptions lose type information and bypass onAfterHandle.
development
Zod — TypeScript-first schema validation with static type inference. Use when building with Zod or asking about schema definitions, type inference, parsing, transformations, refinements, coercion, error handling, or integration with forms, APIs, or tRPC. Fetch live documentation for up-to-date details.
tools
Vite — next-generation frontend build tool with instant dev server and optimized production builds. Use when building with Vite or asking about its APIs, configuration, plugins, SSR, environment variables, or integration with frameworks. Fetch live documentation for up-to-date details.
tools
Upstash — serverless Redis, QStash, and Vector database with per-request pricing optimized for edge and serverless environments. Use when building with Upstash or asking about its Redis client, QStash message queuing, rate limiting, workflows, or vector search. Fetch live documentation for up-to-date details.
tools
Turso — edge-hosted SQLite database built on libSQL with embedded replicas, multi-tenancy, and low-latency global distribution. Use when building with Turso or asking about its libSQL client, embedded replicas, database-per-tenant patterns, auth tokens, sync, or integration with Drizzle or other ORMs. Fetch live documentation for up-to-date details.