Introduction
Status: alpha (v0.0.1). The API is mostly settled but still subject to change before 0.1.0. Use Ingenium for side projects and internal tools; revisit for production once 1.0 lands.
What is Ingenium?
Ingenium is what happens if you fix Express's three structural problems - linear routing, untyped req/res, and per-request allocation - without forcing developers to learn a new mental model. It's the same shape (app.get, app.use, mountable routers, drop-in middleware), with a typed ctx instead of (req, res, next), and a router/dispatcher built for current-decade Node throughput.
The pitch in one sentence: the shortest path from a working Express app to throughput competitive with Hono and Fastify.
Three core ideas
- Typed
ctx- one pooled, strongly-typed context object replaces(req, res, next). Lazy getters for things likequeryandbody, astatescratch space for per-request data, and full TypeScript types for params, headers, and decorated fields. - Return-value reflection - handlers can
returna value and Ingenium writes the right response. Object → JSON, string → text/html,Buffer→ octet-stream,Readable→ stream,undefined→ 204.ctx.json(...)still works when you want explicit control. - Radix-trie router - O(k) lookup with wildcard backtracking, lazy composition, and a dirty-bit recompose so route registration after
listen()Just Works.
Show me the code
import { ingenium } from 'ingenium'
const app = ingenium()
app.use(async (ctx, next) => {
const start = Date.now()
await next()
console.log(`${ctx.method} ${ctx.path} -> ${ctx._statusCode} ${Date.now() - start}ms`)
})
app.get('/', () => 'hello')
app.get('/users/:id', (ctx) => ({ id: ctx.params.id }))
app.post('/echo', async (ctx) => ctx.body.json())
const server = await app.listen(3000)
console.log(`listening on http://localhost:${server.port}`)
That's a full server. No res.send. No body-parser. No app.set('case sensitive routing', true). Return a value and Ingenium reflects it to the wire - object → JSON, string → text/html, Buffer → octet-stream, Readable → stream, undefined → 204. Call ctx.json(...) when you want explicit control over status or headers.
Where to next?
- Quick start - install, write your first handler, run it.
- Migration from Express - the 5-minute side-by-side diff.
- Core concepts - App, Router, path syntax, composition timing.
- Production hardening - the opt-in primitives an API team actually needs in prod.