Skip to content

✨ Feature Proposal: Zero-Boilerplate, Layer-Merged ORM & Types #855

@mrkaashee

Description

@mrkaashee

I want to create an Auth layer that I can reuse across projects — but right now, I can’t truly reuse the table logic, ORM, and types without rewriting or rewiring things in every project.

Summary

Add built-in support in Nuxthub to automatically generate and merge:

  • schemas.* (Zod insert/select/update)
  • Base inferred types
  • Global orm.* namespace

From:

server/db/schema/*  Drizzle tables server/db/schemas/*  Zod schemas server/db/orm/*  ORM logic server/db/types/*  Type extensions

With full Nuxt layer merging support (like current db/schema merging).


1️⃣ Zero Boilerplate

If a developer defines:

server/db/schema/products.ts

Nuxthub automatically provides:

schemas.products.insert schemas.products.select type Product type NewProduct orm.products = { } // will be defined in server/db/orm/products

No manual:

  • createInsertSchema
  • $inferSelect
  • Type exporting
  • Namespace wiring

Developers can still override intentionally.


2️⃣ Layer-Merged ORM (Write Once → Use Everywhere)

Extend existing schema merging to also merge:

server/db/schema/* server/db/schemas/* server/db/orm/* server/db/types/*

🔐 Example: Auth Layer

Auth layer defines:

auth-layer/server/db/schema/users.ts auth-layer/server/db/orm/users/index.ts

Project automatically gets:

orm.users.create() orm.users.getByUsername()

No re-exporting.
No setup.
Write once → available globally via orm.*.


3️⃣ Type Merging Behavior (Important)

Base types are auto-generated from tables:

type User = typeof schema.users.$inferSelect type Product = typeof schema.products.$inferSelect

If any layer or the main project defines:

server/db/types/users.ts

The contents are merged/augmented, not automatically overriding base types.

Meaning:

  • Creating server/db/types/users.ts does NOT override type User
  • Types are only overridden if developer explicitly redeclares:
export type User = { ... }

Otherwise, custom types inside server/db/types/* are simply merged and coexist.

So:

  • Safe by default
  • Explicit override only
  • No accidental type replacement

Why This Matters

🔥 True zero-boilerplate DB architecture
🔥 Reusable backend feature layers (auth, payments, etc.)
🔥 Predictable type behavior (no accidental overrides)
🔥 Consistent DX across projects
🔥 Fully extensible, convention-first design

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions