Zero to API in seconds - Entity-first, type-safe API framework
npm install @zapi-x/core> Zero to API in seconds - Entity-first, type-safe API framework



> ⚠️ Beta Software: APIs may change before v1.0. Use in production at your own risk.
- 🚀 Entity-first - Define your entities, get your API
- 🔒 Type-safe - Full TypeScript support with inference
- 🔌 Framework agnostic - Express, Hono, and more
- 🗄️ Database agnostic - Prisma, and more coming
- 🧩 Plugin system - Auth, timestamps, and custom plugins
- ⚡ Zero config - Sensible defaults, override when needed
``bash`
npm install @zapi-x/coreor
pnpm add @zapi-x/core
`typescript
import { entity, string, text, belongsTo } from "@zapi-x/core"
import { zapi } from "@zapi-x/core"
// 1. Define entities
const user = entity("user", {
email: string.unique(),
name: string.min(1).max(100),
})
.build()
const post = entity("post", {
title: string,
content: text,
author: belongsTo(() => user),
})
.ownedBy("author")
.build()
// 2. Mount to your framework (Express + Prisma example)
import express from "express"
import { expressAdapter, expressDevAuth } from "@zapi-x/core/adapters/express"
import { prisma } from "@zapi-x/core/drivers/prisma"
import { PrismaClient } from "@prisma/client"
const app = express()
const prisma = new PrismaClient()
const api = zapi({
entities: [user, post],
driver: prisma(prisma),
})
app.use("/api", expressAdapter(api, { getUser: expressDevAuth, cors: true }))
app.listen(3000)
`
`typescript
import { entity, string, text, int, bool, datetime, belongsTo, hasMany } from "@zapi-x/core"
const task = entity("task", {
// String fields
title: string.min(1).max(200),
description: text.optional(),
// Other types
priority: int.default(0).min(0).max(3),
completed: bool.default(false),
dueDate: datetime.optional(),
// Relations
project: belongsTo(() => project),
assignee: belongsTo(() => user),
})
.ownedBy("assignee") // Auto-set owner on create
.rules({
create: ["authenticated"],
read: ["everyone"],
update: ["owner", "admin"],
delete: ["admin"],
})
.build()
`
Import only what you need:
`typescript
// Express
import { expressAdapter, expressDevAuth, expressJwtAuth } from "zapi/adapters/express"
// Hono
import { honoAdapter, honoDevAuth, honoJwtAuth, cookieAuth } from "zapi/adapters/hono"
`
`typescript`
// Prisma
import { prisma } from "zapi/drivers/prisma"
`typescript
// Timestamps (adds createdAt/updatedAt globally)
import { timestamps } from "zapi/plugins/timestamps"
// Auth helpers are provided via adapters (dev/jwt) to keep Zapi auth-agnostic
// import { expressDevAuth, expressJwtAuth } from "zapi/adapters/express"
`
Use the generator to create Prisma schema, TypeScript types, and API client:
`typescript
import { generate } from "@zapi-x/generator"
import { entities } from "./entities"
generate(entities, {
outDir: "./generated",
prismaProvider: "sqlite",
})
`
This generates:
- generated/prisma/schema.prisma - Prisma schemagenerated/types.ts
- - TypeScript interfacesgenerated/client.ts
- - Type-safe API client
For each entity, zapi generates:
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | /users | List with filter/sort/pagination |/users
| POST | | Create |/users/:id
| GET | | Get by ID |/users/:id
| PUT | | Update |/users/:id
| DELETE | | Delete |
`bashFiltering
GET /users?filter[role]=admin
MIT © 2025