A minimal Node.js/TypeScript backend framework. A route's shape, validation, and handler live in one call: give it a schema, get a typed context and a runtime check. Handlers are async functions that take a typed context and return a plain value, which becomes the JSON response. No req/res/next, no external HTTP library, no validation library just node:http and a small hand-rolled validator.
npm install @cairnjs/coreimport{cairn}from'@cairnjs/core';constapp=cairn();app.route('GET /users/:id',{params: {id: 'string'},handler: ({ params })=>({id: params.id,name: 'Ada Lovelace'}),});app.route('POST /users',{body: {name: 'string',age: 'number?'},handler: ({ body })=>({created: true, ...body}),});app.listen(3000);Returns an app instance.
pattern is "METHOD /path/:param", e.g. "GET /users/:id".
def:
| field | type | description |
|---|---|---|
params | schema | validated + coerced from URL params |
query | schema | validated + coerced from query string |
body | schema | validated from parsed JSON body |
before | BeforeHook | BeforeHook[] | route-scoped hooks, run before validation |
handler | (ctx) => value | Promise<value> | return value becomes the JSON response |
The schema mini-language is 'string' | 'number' | 'boolean', with a trailing ? for optional. The same schema drives the TypeScript type of ctx.params / ctx.query / ctx.body.
Plugins are functions that receive the app instance:
app.use((app)=>{app.before((ctx)=>{console.log(`${ctx.method}${ctx.path}`);});});Register a global hook that runs before the handler, receiving a mutable ctx. A hook may return an "after" callback that runs once the handler completes.
Returns a typed error. Throw it in a handler or hook to produce a JSON error response with that status:
throwapp.error(404,'not found');Returns a redirect value. Return it from a handler to respond with a 302 + Location header.
Starts a node:http server. Returns the server.
@cairnjs/plugin-examplelogger.app.use(loggerPlugin()).@cairnjs/plugin-authroute-scoped auth guard.before: [authGuard({ key })].
examples/basic-apiminimal CRUD-ish app with the logger plugin.examples/url-shortenera URL shortener dogfooding the framework, with a friction log.
See CONTRIBUTING.md.
See SECURITY.md.
MIT. See LICENSE.
