npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

nuxt-auto-crud

v1.21.0

Published

Exposes RESTful CRUD APIs for your Nuxt app based solely on your database migrations.

Readme

Nuxt Auto CRUD

Note: This module is widely used in MVP development and is rapidly maturing. While currently in Beta, the core API (CRUD) is stable. Breaking changes may still occur in configuration or advanced features. Production use is encouraged with version pinning.

Auto-expose RESTful CRUD APIs for your Nuxt application based solely on your database schema. Minimal configuration required.

Core Philosophy: The main objective of this module is to expose CRUD APIs without the need for writing code. You define your database schema, and nuxt-auto-crud handles the rest.

You don't need to setup an extra server or database to create an MVP of an application. The Nuxt (Nitro) server and SQLite can save you time and money. And you don't need a separate Strapi or Supabase setup to automate your CRUD process. nuxt-auto-crud will help you with that and accelerate your development exponentially.

While this module exposes CRUD APIs, you are expected to build your own frontend application to consume them.

🚀 CRUD APIs are ready to use without code

Once installed, your database tables' CRUD APIs are exposed in a controlled manner:

  • GET /api/:model - List all records
  • POST /api/:model - Create a new record
  • GET /api/:model/:id - Get record by ID
  • PATCH /api/:model/:id - Update record
  • DELETE /api/:model/:id - Delete record

📦 How to install

1. Fullstack Template (Recommended)

Start a new project with everything pre-configured using our template:

npx nuxi init -t gh:clifordpereira/nuxt-auto-crud_template <project-name>
cd <project-name>
bun install
bun db:generate
bun run dev

Template Usage Modes:

  1. Fullstack App: The template includes the nuxt-auto-crud module, providing both the backend APIs and the frontend UI. Watch Demo
  2. Frontend Only: You can use the template just for the frontend. In this case, you don't need to install the module in the frontend app. Instead, you would install nuxt-auto-crud in a separate backend setup (e.g., another Nuxt project acting as the API).

Detailed instructions can be found in https://auto-crud.clifland.in/docs/auto-crud

2. Manual Setup (Existing Project)

If you want to add nuxt-auto-crud to an existing project, follow these steps:

Note: These instructions have been simplified for NuxtHub.

Install dependencies

# Install module and required dependencies
npm install nuxt-auto-crud @nuxthub/core@^0.10.0 drizzle-orm

# Optional: Install auth dependencies if using Session Auth (Recommended)
npm install nuxt-auth-utils nuxt-authorization

npm install --save-dev wrangler drizzle-kit

# Or using bun
bun add nuxt-auto-crud @nuxthub/core@latest drizzle-orm
bun add nuxt-auth-utils nuxt-authorization
bun add --dev wrangler drizzle-kit

Configure Nuxt

Add the modules to your nuxt.config.ts:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxthub/core', 'nuxt-auto-crud'],

  hub: {
    db: 'sqlite',
  },

  autoCrud: {
    schemaPath: 'server/db/schema',
    // auth: false,
    auth: {
      type: 'session', // for Normal Authentication with nuxt-auth-utils
      authentication: true,
      authorization: true,
    },
  },
})

Configure Drizzle

Add the generation script to your package.json:

{
  "scripts": {
    "db:generate": "nuxt db generate"
  }
  // ...
}

Create drizzle.config.ts in your project root:

// drizzle.config.ts
import { defineConfig } from 'drizzle-kit'

export default defineConfig({
  dialect: 'sqlite',
  schema: './server/db/schema/index.ts', // Point to your schema index file
  out: './server/db/migrations'
})

Define your database schema

Create your schema files in server/db/schema/. For example, server/db/schema/users.ts:

// server/db/schema/users.ts
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core'

export const users = sqliteTable('users', {
  id: integer('id').primaryKey({ autoIncrement: true }),
  name: text('name').notNull(),
  email: text('email').notNull().unique(),
  password: text('password').notNull(),
  avatar: text('avatar').notNull(),
  createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
})

Run the project

cd <project-name>
bun db:generate
bun run dev

That's it! 🎉 Your CRUD APIs are now available at /api/users.

Adding New Schemas

To add a new table (e.g., posts), simply create a new file in your schema directory:

// server/db/schema/posts.ts
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core'
import { users } from './users'

export const posts = sqliteTable('posts', {
  id: integer('id').primaryKey({ autoIncrement: true }),
  title: text('title').notNull(),
  content: text('content').notNull(),
  authorId: integer('author_id').references(() => users.id),
  createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
})

Then, ensure it is exported in your server/db/schema/index.ts (if you are using an index file) or that your drizzle.config.ts is pointing to the correct location.

// server/db/schema/index.ts
export * from './users'
export * from './posts'

After adding the file, run the generation script:

bun db:generate

The new API endpoints (e.g., /api/posts) will be automatically available. Watch Demo

Note: The organization.ts and cms.ts files you might see in the playground are just examples and are commented out by default. You should implement a robust schema tailored to your production needs.

3. Backend-only App (API Mode)

If you are using Nuxt as a backend for a separate client application (e.g., mobile app, SPA), you can use this module to quickly expose REST APIs.

In this case, you might handle authentication differently (e.g., validating tokens in middleware) or disable the built-in auth checks if you have a global auth middleware.

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-auto-crud'],
  autoCrud: {
    schemaPath: 'server/db/schema',
    // auth: false, // Uncomment this line for testing APIs without auth   
    auth: {
      type: 'jwt', // for app providing backend apis only
      authentication: true,
      authorization: true,
      jwtSecret: process.env.NUXT_JWT_SECRET || 'test-secret-key-123',
    },
  },
})

Note: Remember to add your NUXT_JWT_SECRET in .env.

You should also configure drizzle.config.ts correctly:

// drizzle.config.ts
import { defineConfig } from 'drizzle-kit'

export default defineConfig({
  dialect: 'sqlite',
  schema: './server/db/schema/index.ts',
  out: './server/db/migrations',
  tablesFilter: ['!_hub_migrations'],
})

🔐 Authentication Configuration

The module enables authentication by default. To test APIs without authentication, you can set auth: false.

Session Auth (Default)

Requires nuxt-auth-utils and nuxt-authorization to be installed in your project.

npm install nuxt-auth-utils nuxt-authorization
export default defineNuxtConfig({
  modules: [
    'nuxt-auth-utils',
    'nuxt-authorization',
    'nuxt-auto-crud'
  ],
  autoCrud: {
    auth: {
      type: 'session',
      authentication: true, // Enables requireUserSession() check
      authorization: true // Enables authorize(model, action) check
    }
  }
})

JWT Auth

Useful for backend-only apps. Does not require nuxt-auth-utils.

export default defineNuxtConfig({
  autoCrud: {
    auth: {
      type: 'jwt',
      authentication: true,
      jwtSecret: process.env.JWT_SECRET,
      authorization: true
    }
  }
})

Disabling Auth

You can disable authentication entirely for testing or public APIs.

export default defineNuxtConfig({
  autoCrud: {
    auth: {
      authentication: false,
      authorization: false
    }
    // OR simply:
    // auth: false
  }
})

🧪 Testing

This module is tested using Vitest.

  • Unit Tests: We cover utility functions and helpers.
  • E2E Tests: We verify the API endpoints using a real Nuxt server instance.

To run the tests locally:

npm run test

🛡️ Public View Configuration (Field Visibility)

You can define which fields are visible to unauthenticated (guest) users in your nuxt.config.ts.

Note: Access control (RBAC) - determining who can access what - is expected to be handled by your database/permissions system (using nuxt-authorization). This configuration only controls the serialization of the response for guests.

// nuxt.config.ts
export default defineNuxtConfig({
  autoCrud: {
    resources: {
      // Guest View: Only these columns are visible to unauthenticated users.
      // Access control (who can list/read) is managed by your DB permissions.
      users: ['id', 'name', 'avatar'], 
    },
  },
})

👤 Owner-based Permissions (RBAC)

In addition to standard create, read, update, and delete permissions, you can assign Ownership Permissions:

  • list: Allows a user to view a list of active records (status='active').
  • list_all: Allows a user to view all records, including inactive ones (e.g., status='inactive', 'draft').
  • update_own: Allows a user to update a record only if they created it.
  • delete_own: Allows a user to delete a record only if they created it.

How it works: The module checks for ownership using the following logic:

  1. Standard Tables: Checks if the record has a createdBy (or userId) column that matches the logged-in user's ID.
  2. Users Table: Checks if the record being accessed is the user's own profile (id matches).

Prerequisites: Ensure your schema includes a createdBy field for resources where you want this behavior:

export const posts = sqliteTable('posts', {
  // ...
  createdBy: integer('created_by'), // Recommended
})

⚠️ Known Issues

  • Automatic Relation Expansion: The module tries to automatically expand foreign keys (e.g., user_id -> user: { name: ... }). However, this relies on the foreign key column name matching the target table name (e.g., user_id for users).
    • Limitation: If you have custom FK names like customer_id or author_id pointing to users, the automatic expansion will not work yet.
    • Workaround: Ensure your FK columns follow the tablename_id convention where possible for now.

🎮 Try the Playground

Want to see it in action? Clone this repo and try the playground:

# Clone the repository
git clone https://github.com/clifordpereira/nuxt-auto-crud.git
cd nuxt-auto-crud

# Install dependencies (parent folder)
bun install

# Run the playground (Fullstack)
cd playground
bun install
bun db:generate
bun run dev

📖 Usage Examples

Create a Record

const user = await $fetch("/api/users", {
  method: "POST",
  body: {
    name: "Cliford Pereira",
    email: "[email protected]",
    bio: "Full-Stack Developer",
  },
});

Get All Records

const users = await $fetch("/api/users");

Get Record by ID

const user = await $fetch("/api/users/1");

Update a Record

const updated = await $fetch("/api/users/1", {
  method: "PATCH",
  body: {
    bio: "Updated bio",
  },
});

Delete a Record

await $fetch("/api/users/1", {
  method: "DELETE",
});

Note: If authentication is enabled (default):

  • Fullstack App: The module integrates with nuxt-auth-utils, so session cookies are handled automatically.
  • Backend-only App: You must include the Authorization: Bearer <token> header in your requests.

Configuration

Module Options


export default defineNuxtConfig({
  autoCrud: {
    // Path to your database schema file (relative to project root)
    schemaPath: "server/db/schema", // default
    
    // Authentication configuration (see "Authentication Configuration" section)
    auth: {
        // ...
    },

    // Public Guest View Configuration (Field Visibility)
    resources: {
        users: ['id', 'name', 'avatar'],
    },
  },
});

Protected Fields

By default, the following fields are protected from updates:

  • id
  • createdAt
  • created_at
  • updatedAt
  • updated_at

You can customize updatable fields in your schema by modifying the modelMapper.ts utility.

Hidden Fields

By default, the following fields are hidden from API responses for security:

  • password
  • secret
  • token

You can customize hidden fields by modifying the modelMapper.ts utility.

🔧 Requirements

  • Nuxt 3 or 4
  • Drizzle ORM (SQLite)
  • NuxtHub >= 0.10.0

🔗 Other Helpful Links

🤝 Contributing

Contributions are welcome! Please check out the contribution guide.

📝 License

MIT License

👨‍💻 Author

Made with ❤️ by Cliford Pereira