@otdoges/chadjs
v0.1.0
Published
An ergonomic, Bun-first web framework for chads. Inspired by Elysia.
Downloads
73
Maintainers
Readme
chadjs
An ergonomic, Bun-first web framework for chads. Inspired by Elysia.
bun add @otdoges/chadjsQuick start
import { Chad, t } from "@otdoges/chadjs"
new Chad()
.state("version", "0.1.0")
.decorate("db", { users: [] as string[] })
.derive(({ headers }) => ({ viewer: headers["x-user"] ?? "anonymous" }))
.onBeforeHandle(({ set }) => set.headers.set("x-powered-by", "chadjs"))
.group("/api", (api) =>
api.get(
"/users/:id",
({ params, viewer }) => ({ id: params.id, viewer }),
{ params: t.Object({ id: t.Number() }) },
),
)
.post("/signup", ({ body }) => body, {
body: t.Object({
email: t.Email(),
role: t.Enum(["admin", "user"] as const),
nickname: t.Optional(t.String()),
}),
})
.get("/events", ({ stream }) =>
stream(
(async function* () {
yield { event: "tick", data: { count: 1 } }
yield { event: "tick", data: { count: 2 } }
})(),
{ sse: true },
),
)
.listen(3000)Features
- Routing —
get/post/put/patch/delete/head/options/all/route,:param,:param?optional segments,*wildcard, trie router. Static > param > wildcard priority. - Composition —
.group(prefix, callback),.guard(options, callback),.use(plugin),.mount(path, app)for WinterCG-compatible apps. - Context extension —
.state,.decorate,.derive(pre-validation),.resolve(post-validation),.macro(reusable named hook bundles). - Full lifecycle —
onRequest→onParse→onTransform→derive→resolve→onBeforeHandle→ handler →onAfterHandle→onMapResponse→onResponse→onAfterResponse. Per-route arrays supported.onError,onStart,onStopavailable. - Validation —
t.String,t.Number,t.Numeric,t.Integer,t.Boolean,t.BooleanString,t.Literal,t.Enum,t.Array,t.Tuple,t.Object,t.Record,t.Partial,t.Required,t.Pick,t.Omit,t.Optional,t.Nullable,t.Nullish,t.Null,t.Undefined,t.Union,t.Intersect,t.RegExp,t.Email,t.UUID,t.URL,t.Date,t.File,t.Files,t.Cookie,t.Any. All coerce + check. - Cookies —
ctx.cookie.get/set/deletewithhttpOnly,secure,sameSite,maxAge,domain,path,expires. Signed cookies viacookie: { secrets, sign: [...] }. - Streaming & SSE —
ctx.stream(asyncIterable, { sse: true })for SSE. Return an async generator directly and it streams automatically. - WebSocket —
.ws(path, { open, message, close, drain, error })wired to Bun's native WebSocket. - Errors —
ChadError,ValidationError,NotFoundError,ParseError,UnauthorizedError,ForbiddenError,InvalidCookieSignatureError. Register custom errors via.error({ Name: Class }). - Type extraction —
Static<typeof schema>extracts the TypeScript type from anyt.*schema. - Runtime-agnostic —
app.handle(request)/app.fetchreturn nativeResponse.app.listen(port | options)for Bun.
Layout
src/
chad.ts # Chad class + lifecycle pipeline
context.ts # Context, cookies (signed), parsing, streaming
router.ts # Segment trie router (static > param > wildcard, optional segments, mount)
schema.ts # t.* runtime validators
errors.ts # ChadError hierarchy
types.ts # Shared types
index.ts # Public exportsTest
bun testScaffold a new app
bun create chad-app my-appLicense
MIT
