Framework Agnostic
Works with Express, Native Node.js HTTP, or any framework. Not locked into a specific ecosystem.
Type-safe, config-based API contracts for client and server
import { route } from '@adi-family/http'
import { z } from 'zod'
export const getUserConfig = {
method: 'GET',
route: route.dynamic(
'/api/users/:id',
z.object({ id: z.string() })
),
response: {
schema: z.object({
id: z.string(),
name: z.string(),
email: z.string().email()
})
}
} as constimport express from 'express'
import { handler } from '@adi-family/http'
import { serveExpress } from '@adi-family/http-express'
import { getUserConfig } from './contracts'
const getUserHandler = handler(getUserConfig, async (ctx) => {
const user = await db.users.findById(ctx.params.id)
return user
})
const app = express()
app.use(express.json())
serveExpress(app, [getUserHandler])
app.listen(3000)import { handler } from '@adi-family/http'
import { serveNative } from '@adi-family/http-native'
import { getUserConfig } from './contracts'
const getUserHandler = handler(getUserConfig, async (ctx) => {
const user = await db.users.findById(ctx.params.id)
return user
})
serveNative([getUserHandler], { port: 3000 })import { BaseClient } from '@adi-family/http'
import { getUserConfig } from './contracts'
const client = new BaseClient({
baseUrl: 'http://localhost:3000'
})
// Fully type-safe!
const user = await client.run(getUserConfig, {
params: { id: '123' }
})
console.log(user.name) // TypeScript knows this exists!# Core library
npm install @adi-family/http zod
# Framework adapters
npm install @adi-family/http-express # For Express
npm install @adi-family/http-native # For Native Node.js# Core library
bun add @adi-family/http zod
# Framework adapters
bun add @adi-family/http-express # For Express
bun add @adi-family/http-native # For Native Node.js# Core library
pnpm add @adi-family/http zod
# Framework adapters
pnpm add @adi-family/http-express # For Express
pnpm add @adi-family/http-native # For Native Node.js