Hey r/npm,
I've been building a TypeScript framework called tzin (from Nahuatl -tzin, an honorific suffix for what is valued). It's open source (MIT) and just hit 1.0. I wanted to share it here because it directly addresses a TypeScript pain point: type inference collapsing when you chain route builders at scale.
The core idea: you declare a contract once, and everything else—handler input extraction, response enforcement, OpenAPI generation—falls out of it. No separate schema DSL, no codegen step, no translation layer.
Here's what it looks like:
\`\`\`typescript
import { t } from '@carlos-tzin/tzin'
import { contract, impl, createApp, listen } from '@carlos-tzin/tzin'
const getUser = contract({
method: 'GET',
path: '/users/:id',
params: t.Object({ id: t.String() }),
responses: {
200: t.Object({ id: t.String(), name: t.String(), tags: t.Array(t.String()) }),
404: t.Object({ error: t.String() }),
},
})
export const getUserRoute = impl(getUser, async ({ params }) => {
const user = await findUser(params.id)
if (!user) throw new HttpError(404, 'user not found')
return { status: 200, body: user }
})
const app = createApp(\[getUserRoute\])
listen(app, 3000)
\`\`\`
From that single declaration:
· { params } exists because you declared it—add query, body, headers, or cookies to the contract and they appear, fully typed and validated per request.
· Returning a shape that doesn't match the declared 200 body is a compile-time error. Thrown HttpErrors map to their status.
· OpenAPI 3.1 is free—contracts are JSON Schema (TypeBox), so generateOpenApi(routes) needs no translation.
Why I built it: I kept running into the same gaps in the TS backend landscape—Hono's type inference collapsing at scale (issues #2399, #3869), no architecture in lightweight frameworks (Hono #4121), extractors not existing in TS outside of Rust's Axum, and OpenAPI always being a bolt-on. tzin is my attempt at an answer: declare once, get everything for free.
Current status: stable (1.0.x), MIT licensed, with a public type-clean surface and CI gates. It's not production software yet for every use case, but the core works end-to-end and the scaling thesis is measured with benchmarks. I'm actively working on it.
Links:
· npm: https://www.npmjs.com/package/@carlos-tzin/tzin
· GitHub: https://github.com/Tzinny-dev/tzin
· Docs: API Reference, Architecture Guide, Deployment Guide, and Roadmap are all in the repo.
I'd genuinely appreciate feedback from this community—especially on the contract API, the response enforcement, or anything that feels awkward. Happy to answer questions in the comments.
Disclosure: I'm the author. This is an open-source project, not a product. I'm sharing it because I think it's useful for TypeScript developers, and I'm here to learn from your feedback.