elysia-architecture
About elysia-architecture
A portable architecture skill for organizing Elysia HTTP applications, defining file layout, naming, and ownership boundaries. It is intended for scaffolding, applying, or reviewing feature modules, while leaving framework API details to current Elysia documentation.
Key features
- 01Organize features under domain modules
- 02Separate routes, schemas, and domain logic
- 03Keep route files focused and thin
- 04Define imports and cross-feature boundaries
- 05Use extensions for matching stack components
Use cases
- 01Scaffold a new Elysia feature module
- 02Place endpoints and schemas consistently
- 03Review an application tree against architecture rules
- 04Set boundaries between routes and services
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ dobroslavradosavljevic/ skills --skill elysia-architectureAfter installing, type/elysia-architecturein Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
agents/openai.yamlreferences/checklist.mdexamples.mdrules.mdtree.mdwith-api-key-auth.mdwith-capability-authz.mdwith-cron.mdwith-domain-packages.mdwith-drizzle.mdwith-effect.mdwith-env.mdwith-http-errors.mdwith-observability.mdwith-openapi.mdwith-service-auth.mdwith-session-auth.mdwith-shared-plugins.mdwith-vitest.mdwith-webhooks.mdDetails
From the project READMEElysia Architecture
Portable house style for Elysia HTTP apps. Use this skill alone — it does not depend on other skills.
Job: where code lives, how folders/files are named, and ownership boundaries.
Not this skill: Elysia API quirks, plugin lifecycle details, Eden, adapters, or latest framework docs. Prefer current Elysia docs for those.
If the target repo already documents architecture (e.g. AGENTS.md) and it
conflicts, repo wins unless the user asks to migrate toward this skill.
Stack defaults (core)
| Piece | Default |
|---|---|
| Runtime | Bun (Node/adapters OK if the app already uses them) |
| HTTP | Elysia feature plugins under src/modules/<feature>/ |
| Version | Elysia 1.4 at ≥ 1.4.30 (security floor; never build route schemas from untrusted input). Elysia 2 is beta — keep house-style code on 1.4 until it ships stable |
| Module layout | routes/ + schema/ + domain logic folder |
| Tests | Vitest under tests/ (unit / integration projects) when the repo uses Vitest |
Domain logic may be plain TypeScript modules. Load matching with-* extensions when those stacks are present (see below).
Modes
- Scaffold — new feature module from checklist.md + tree.md.
- Apply — place new endpoints/schemas/services in the canonical spots.
- Review — compare the tree to rules.md; propose moves; do not invent a parallel layout.
Hard rules (core)
- Feature =
src/modules/<feature>/. Group by domain (billing,users), not by technical layer at the app root. - One route file = one exported
constElysia plugin with a stablename, and typically one HTTP verb (or a tight related group). Do not pack unrelated verbs into one file. Do notexport function makeXRoutes(...). routes/index.tsis a mount table only —.use(child)(+prefix). No handlers, no domain logic, no shared mappers.- Schemas live under
schema/(body,response,query,paramsas needed). Do not dump DTOs into route files or invent parallel hand-written response interfaces when schemas already define the contract. - Routes stay thin. HTTP concerns (auth guards, status mapping, request/response) in the route file; business rules in services (or plain domain modules).
- No route factories / shared HTTP wrappers. Do not invent
makeSyncGet,mapXToHttp, orutils/*-http.tsthat wrap handlers. Inline the edge in each route file. - Import process resources. Do not inject them. Database, Effect runtime, env, queues:
import { db } from "…",import { runtime } from "…". Forbidden:export function cmsRoutes(db: Db),.decorate("db", db)/.decorate("runtime", runtime)on feature routes, or passing those values through mount-table arguments. Shared-package plugins may take options (origins, prefix); apps still import their own singletons. - Map failures at the HTTP edge only. Public bodies stay small (e.g.
{ error: string }+ status). Do not leak internal causes. - Do not grow
utils/for HTTP. Preferschema/, services/domain, or inlined route edges. - Naming: folder = noun/domain; file = action or aspect (
create.ts,status.ts). Do not repeat the parent folder in the leaf name (billing/billing-status.ts→billing/routes/status.ts). - Import direction: routes → schema + services; services must not import routes. Cross-feature deps go through services/shared packages, not route→route imports.
- Mount feature trees from the app entry (or a parent feature’s mount table).
Details, anti-patterns, and examples: rules.md, tree.md, examples.md.
Progressive disclosure
| Need | Read |
|---|---|
| Canonical trees + naming | references/tree.md |
| Enforce rules + anti-patterns | references/rules.md |
| Scaffold / review checklists | references/checklist.md |
| Good vs bad layouts | references/examples.md |
| Optional stack overlays | Extensions below |
Extensions
Load an extension only when the matching stack is present (or the user asks). Extensions add rules; they do not replace the core tree.
| When | Extension |
|---|---|
| Effect services / Layers / tagged errors | with-effect.md |
T3 Env / packages must not read process.env | with-env.md |
Session auth mount + { auth: true } macro | with-session-auth.md |
| Capabilities / grants / identity permissions | with-capability-authz.md |
| Bearer API keys on a jobs/public API | with-api-key-auth.md |
| Drizzle schema package + DB in services | with-drizzle.md |
| OpenAPI derived from route schemas | with-openapi.md |
| Request logs + OTEL + Effect tracer | with-observability.md |
| Stable public error body + edge mapping | with-http-errors.md |
Domain in packages/*, HTTP in app modules | with-domain-packages.md |
| Shared vs app-local Elysia plugins | with-shared-plugins.md |
| In-process cron ticks | with-cron.md |
| Provider webhooks | with-webhooks.md |
| Internal shared-secret routes | with-service-auth.md |
Vitest — Eden treaty(app) / what to test | with-vitest.md |