Skip to content

NevrThe Entity-First TypeScript Framework

Define your data model once. Get a type-safe API, database schema, auth, and client — automatically.

Nevr Framework Hero

Why Nevr?

Building backends today means gluing together an ORM, a framework, validation libraries, and auth middleware — then manually keeping types in sync.

Nevr changes that. Define your entity once, and everything else is derived from it.


What You Get

typescript
// Define your entity — this is your entire backend for a resource
const post = entity("post", {
  title: string.min(1).max(200),
  content: text,
  author: belongsTo(() => user),
})
.ownedBy("author")
.rules({
    create: ["authenticated"],
    read: ["everyone"],
    update: ["owner"],
    delete: ["owner", "admin"],
  })

From this single definition, you get:

  • POST /api/posts — Create (validated, auth-protected)
  • GET /api/posts — List (filtered, sorted, paginated)
  • GET /api/posts/:id — Read (with relation includes)
  • PUT /api/posts/:id — Update (ownership enforced)
  • DELETE /api/posts/:id — Delete (ownership enforced)
  • Prisma schema auto-generated
  • TypeScript types inferred end-to-end (from DB to React)

The Nevr Difference

The Traditional Way

  • Manual controller files
  • Validation logic scattered
  • Types synced manually
  • Auth middleware spaghetti
  • No built-in rollback

The Nevr Way

  • Entity-First: One definition powers everything
  • Automatic API: CRUD + Custom Actions
  • Type-Safe: DB to React inference
  • Workflow Engine: Built-in Sagas
  • Plugins: Drop-in Auth & Payments

Beyond CRUD

Nevr provides the architectural primitives needed to build scalable, real-world applications.

Robust Workflows

Define complex multi-step operations with automatic failure handling.

typescript
action().workflow([
  step("reserve", inventory.reserve, inventory.release),
  step("charge", stripe.charge, stripe.refund),
  step("fulfill", shipping.create),
])

Service Container

Functional dependency injection that keeps your code testable and decoupled.

typescript
// Register once, use anywhere
api.register(Payment, new Stripe())

const payments = ctx.resolve(Payment)

Remote Data

Merge data from external APIs as if it were in your local database.

typescript
// User in DB, Sub in Stripe
belongsTo(() => sub).remote("stripe")

// API Response: { user, sub }

Ready to build?

Start building in 60 seconds.

Get Started →

Released under the MIT License.